diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2005-09-07 21:28:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-08 11:14:11 -0400 |
commit | 8920e8f94c44e31a73bdf923b04721e26e88cadd (patch) | |
tree | 7a0195643c37c63335224358256fab8cd445a671 /net/socket.c | |
parent | 5aa3b610a7330c3cd6f0cb264d2189a3a1dcf534 (diff) |
[PATCH] Fix 32bit sendmsg() flaw
When we copy 32bit ->msg_control contents to kernel, we walk the same
userland data twice without sanity checks on the second pass.
Second version of this patch: the original broke with 64-bit arches
running 32-bit-compat-mode executables doing sendmsg() syscalls with
unaligned CMSG data areas
Another thing is that we use kmalloc() to allocate and sock_kfree_s()
to free afterwards; less serious, but also needs fixing.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Chris Wright <chrisw@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/net/socket.c b/net/socket.c index e1bd5d84d7bf..c699e93c33d7 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1745,10 +1745,11 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) | |||
1745 | goto out_freeiov; | 1745 | goto out_freeiov; |
1746 | ctl_len = msg_sys.msg_controllen; | 1746 | ctl_len = msg_sys.msg_controllen; |
1747 | if ((MSG_CMSG_COMPAT & flags) && ctl_len) { | 1747 | if ((MSG_CMSG_COMPAT & flags) && ctl_len) { |
1748 | err = cmsghdr_from_user_compat_to_kern(&msg_sys, ctl, sizeof(ctl)); | 1748 | err = cmsghdr_from_user_compat_to_kern(&msg_sys, sock->sk, ctl, sizeof(ctl)); |
1749 | if (err) | 1749 | if (err) |
1750 | goto out_freeiov; | 1750 | goto out_freeiov; |
1751 | ctl_buf = msg_sys.msg_control; | 1751 | ctl_buf = msg_sys.msg_control; |
1752 | ctl_len = msg_sys.msg_controllen; | ||
1752 | } else if (ctl_len) { | 1753 | } else if (ctl_len) { |
1753 | if (ctl_len > sizeof(ctl)) | 1754 | if (ctl_len > sizeof(ctl)) |
1754 | { | 1755 | { |