X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=crypto%2Faf_alg.c;h=7f8b7edcadca3f64168e3451e52642a485a5d51f;hb=99fa0ad92c4fd8b529c89b3640b42323984be761;hp=4665b79c729ac1d59d699907d3e5c75628231cdb;hpb=103004749235915190b81108f6bf4dbf53f220b9;p=cascardo%2Flinux.git diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 4665b79c729a..7f8b7edcadca 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -188,7 +188,7 @@ static int alg_setkey(struct sock *sk, char __user *ukey, err = type->setkey(ask->private, key, keylen); out: - sock_kfree_s(sk, key, keylen); + sock_kzfree_s(sk, key, keylen); return err; } @@ -215,6 +215,13 @@ static int alg_setsockopt(struct socket *sock, int level, int optname, goto unlock; err = alg_setkey(sk, optval, optlen); + break; + case ALG_SET_AEAD_AUTHSIZE: + if (sock->state == SS_CONNECTED) + goto unlock; + if (!type->setauthsize) + goto unlock; + err = type->setauthsize(ask->private, optlen); } unlock: @@ -338,49 +345,31 @@ static const struct net_proto_family alg_family = { .owner = THIS_MODULE, }; -int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len, - int write) +int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len) { - unsigned long from = (unsigned long)addr; - unsigned long npages; - unsigned off; - int err; - int i; + size_t off; + ssize_t n; + int npages, i; - err = -EFAULT; - if (!access_ok(write ? VERIFY_READ : VERIFY_WRITE, addr, len)) - goto out; + n = iov_iter_get_pages(iter, sgl->pages, len, ALG_MAX_PAGES, &off); + if (n < 0) + return n; - off = from & ~PAGE_MASK; - npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; - if (npages > ALG_MAX_PAGES) - npages = ALG_MAX_PAGES; - - err = get_user_pages_fast(from, npages, write, sgl->pages); - if (err < 0) - goto out; - - npages = err; - err = -EINVAL; + npages = (off + n + PAGE_SIZE - 1) >> PAGE_SHIFT; if (WARN_ON(npages == 0)) - goto out; - - err = 0; + return -EINVAL; sg_init_table(sgl->sg, npages); - for (i = 0; i < npages; i++) { + for (i = 0, len = n; i < npages; i++) { int plen = min_t(int, len, PAGE_SIZE - off); sg_set_page(sgl->sg + i, sgl->pages[i], plen, off); off = 0; len -= plen; - err += plen; } - -out: - return err; + return n; } EXPORT_SYMBOL_GPL(af_alg_make_sg); @@ -405,7 +394,7 @@ int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con) if (cmsg->cmsg_level != SOL_ALG) continue; - switch(cmsg->cmsg_type) { + switch (cmsg->cmsg_type) { case ALG_SET_IV: if (cmsg->cmsg_len < CMSG_LEN(sizeof(*con->iv))) return -EINVAL;