* This is used for tunneling the sctp_bindx() request through sctp_setsockopt()
  * from userspace.
  *
- * We don't use copy_from_user() for optimization: we first do the
- * sanity checks (buffer size -fast- and access check-healthy
- * pointer); if all of those succeed, then we can alloc the memory
- * (expensive operation) needed to copy the data to kernel. Then we do
- * the copying without checking the user space area
- * (__copy_from_user()).
- *
  * On exit there is no need to do sockfd_put(), sys_setsockopt() does
  * it.
  *
        if (unlikely(addrs_size <= 0))
                return -EINVAL;
 
-       /* Check the user passed a healthy pointer.  */
-       if (unlikely(!access_ok(VERIFY_READ, addrs, addrs_size)))
-               return -EFAULT;
-
-       /* Alloc space for the address array in kernel memory.  */
-       kaddrs = kmalloc(addrs_size, GFP_USER | __GFP_NOWARN);
-       if (unlikely(!kaddrs))
-               return -ENOMEM;
-
-       if (__copy_from_user(kaddrs, addrs, addrs_size)) {
-               kfree(kaddrs);
-               return -EFAULT;
-       }
+       kaddrs = vmemdup_user(addrs, addrs_size);
+       if (unlikely(IS_ERR(kaddrs)))
+               return PTR_ERR(kaddrs);
 
        /* Walk through the addrs buffer and count the number of addresses. */
        addr_buf = kaddrs;
        while (walk_size < addrs_size) {
                if (walk_size + sizeof(sa_family_t) > addrs_size) {
-                       kfree(kaddrs);
+                       kvfree(kaddrs);
                        return -EINVAL;
                }
 
                 * causes the address buffer to overflow return EINVAL.
                 */
                if (!af || (walk_size + af->sockaddr_len) > addrs_size) {
-                       kfree(kaddrs);
+                       kvfree(kaddrs);
                        return -EINVAL;
                }
                addrcnt++;
        }
 
 out:
-       kfree(kaddrs);
+       kvfree(kaddrs);
 
        return err;
 }
  * land and invoking either sctp_connectx(). This is used for tunneling
  * the sctp_connectx() request through sctp_setsockopt() from userspace.
  *
- * We don't use copy_from_user() for optimization: we first do the
- * sanity checks (buffer size -fast- and access check-healthy
- * pointer); if all of those succeed, then we can alloc the memory
- * (expensive operation) needed to copy the data to kernel. Then we do
- * the copying without checking the user space area
- * (__copy_from_user()).
- *
  * On exit there is no need to do sockfd_put(), sys_setsockopt() does
  * it.
  *
                                      sctp_assoc_t *assoc_id)
 {
        struct sockaddr *kaddrs;
-       gfp_t gfp = GFP_KERNEL;
        int err = 0;
 
        pr_debug("%s: sk:%p addrs:%p addrs_size:%d\n",
        if (unlikely(addrs_size <= 0))
                return -EINVAL;
 
-       /* Check the user passed a healthy pointer.  */
-       if (unlikely(!access_ok(VERIFY_READ, addrs, addrs_size)))
-               return -EFAULT;
-
-       /* Alloc space for the address array in kernel memory.  */
-       if (sk->sk_socket->file)
-               gfp = GFP_USER | __GFP_NOWARN;
-       kaddrs = kmalloc(addrs_size, gfp);
-       if (unlikely(!kaddrs))
-               return -ENOMEM;
-
-       if (__copy_from_user(kaddrs, addrs, addrs_size)) {
-               err = -EFAULT;
-       } else {
-               err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id);
-       }
+       kaddrs = vmemdup_user(addrs, addrs_size);
+       if (unlikely(IS_ERR(kaddrs)))
+               return PTR_ERR(kaddrs);
 
-       kfree(kaddrs);
+       err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id);
+       kvfree(kaddrs);
 
        return err;
 }