Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc vfs updates from Al Viro: "All kinds of misc stuff, without any unifying topic, from various people. Neil's d_anon patch, several bugfixes, introduction of kvmalloc analogue of kmemdup_user(), extending bitfield.h to deal with fixed-endians, assorted cleanups all over the place..." * 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (28 commits) alpha: osf_sys.c: use timespec64 where appropriate alpha: osf_sys.c: fix put_tv32 regression jffs2: Fix use-after-free bug in jffs2_iget()'s error handling path dcache: delete unused d_hash_mask dcache: subtract d_hash_shift from 32 in advance fs/buffer.c: fold init_buffer() into init_page_buffers() fs: fold __inode_permission() into inode_permission() fs: add RWF_APPEND sctp: use vmemdup_user() rather than badly open-coding memdup_user() snd_ctl_elem_init_enum_names(): switch to vmemdup_user() replace_user_tlv(): switch to vmemdup_user() new primitive: vmemdup_user() memdup_user(): switch to GFP_USER eventfd: fold eventfd_ctx_get() into eventfd_ctx_fileget() eventfd: fold eventfd_ctx_read() into eventfd_read() eventfd: convert to use anon_inode_getfd() nfs4file: get rid of pointless include of btrfs.h uvc_v4l2: clean copyin/copyout up vme_user: don't use __copy_..._user() usx2y: don't bother with memdup_user() for 16-byte structure ...
This commit is contained in:
@@ -968,13 +968,6 @@ int sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw)
|
||||
* 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.
|
||||
*
|
||||
@@ -1004,25 +997,15 @@ static int sctp_setsockopt_bindx(struct sock *sk,
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1033,7 +1016,7 @@ static int sctp_setsockopt_bindx(struct sock *sk,
|
||||
* causes the address buffer to overflow return EINVAL.
|
||||
*/
|
||||
if (!af || (walk_size + af->sockaddr_len) > addrs_size) {
|
||||
kfree(kaddrs);
|
||||
kvfree(kaddrs);
|
||||
return -EINVAL;
|
||||
}
|
||||
addrcnt++;
|
||||
@@ -1063,7 +1046,7 @@ static int sctp_setsockopt_bindx(struct sock *sk,
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(kaddrs);
|
||||
kvfree(kaddrs);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -1321,13 +1304,6 @@ out_free:
|
||||
* 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.
|
||||
*
|
||||
@@ -1343,7 +1319,6 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
|
||||
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",
|
||||
@@ -1352,24 +1327,12 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
|
||||
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;
|
||||
kaddrs = vmemdup_user(addrs, addrs_size);
|
||||
if (unlikely(IS_ERR(kaddrs)))
|
||||
return PTR_ERR(kaddrs);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
kfree(kaddrs);
|
||||
err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id);
|
||||
kvfree(kaddrs);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
Reference in New Issue
Block a user