summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorDan Carpenter <dan.carpenter@oracle.com>2013-11-27 15:40:21 +0300
committerBen Hutchings <ben@decadent.org.uk>2014-01-03 04:33:33 +0000
commit26fe7ef27e2db83b33ac7fb1cb3bca829cbcb8e2 (patch)
treed0ed37e1fcd37c706dcbe20e9659d1444fa6352e /net
parentb38ecb9bbbb42b71833ff4439283f51120a35c1a (diff)
net: clamp ->msg_namelen instead of returning an error
[ Upstream commit db31c55a6fb245fdbb752a2ca4aefec89afabb06 ] If kmsg->msg_namelen > sizeof(struct sockaddr_storage) then in the original code that would lead to memory corruption in the kernel if you had audit configured. If you didn't have audit configured it was harmless. There are some programs such as beta versions of Ruby which use too large of a buffer and returning an error code breaks them. We should clamp the ->msg_namelen value instead. Fixes: 1661bf364ae9 ("net: heap overflow in __audit_sockaddr()") Reported-by: Eric Wong <normalperson@yhbt.net> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Tested-by: Eric Wong <normalperson@yhbt.net> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'net')
-rw-r--r--net/compat.c2
-rw-r--r--net/socket.c2
2 files changed, 2 insertions, 2 deletions
diff --git a/net/compat.c b/net/compat.c
index 3312574e1cf6..41724c9d32d5 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -72,7 +72,7 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
__get_user(kmsg->msg_flags, &umsg->msg_flags))
return -EFAULT;
if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
- return -EINVAL;
+ kmsg->msg_namelen = sizeof(struct sockaddr_storage);
kmsg->msg_name = compat_ptr(tmp1);
kmsg->msg_iov = compat_ptr(tmp2);
kmsg->msg_control = compat_ptr(tmp3);
diff --git a/net/socket.c b/net/socket.c
index 8021b0f5c55e..d4faaded1a9d 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1885,7 +1885,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
return -EFAULT;
if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
- return -EINVAL;
+ kmsg->msg_namelen = sizeof(struct sockaddr_storage);
return 0;
}