From: Jiri Pirko <jpirko@redhat.com> Date: Thu, 12 Feb 2009 11:06:08 +0100 Subject: [net] ipv6: check length of users's optval in setsockopt Message-id: 20090212100607.GA3425@psychotron.englab.brq.redhat.com O-Subject: [RHEL5.4 patch] BZ484977 net: ipv6: Check length of optval provided by user in setsockopt() Bugzilla: 484977 RH-Acked-by: Neil Horman <nhorman@redhat.com> RH-Acked-by: David Miller <davem@redhat.com> RH-Acked-by: Thomas Graf <tgraf@redhat.com> BZ484977 https://bugzilla.redhat.com/show_bug.cgi?id=484977 Description: Check length of setsockopt's optval, which provided by user, before copy it from user space. For POSIX compliant, return -EINVAL for setsockopt of short lengths. Upstream: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=a28398ba6112be28c6a92aacf06aca1979b454b7 Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=1691076 Test: Booted on x86_64 and tested with reproducer. Jirka diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 3733ca7..58d9299 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -552,7 +552,10 @@ done: case IPV6_DROP_MEMBERSHIP: { struct ipv6_mreq mreq; - + + if (optlen < sizeof(struct ipv6_mreq)) + goto e_inval; + retv = -EPROTO; if (inet_sk(sk)->is_icsk) break; @@ -572,7 +575,7 @@ done: { struct ipv6_mreq mreq; - if (optlen != sizeof(struct ipv6_mreq)) + if (optlen < sizeof(struct ipv6_mreq)) goto e_inval; retv = -EFAULT; @@ -591,6 +594,9 @@ done: struct group_req greq; struct sockaddr_in6 *psin6; + if (optlen < sizeof(struct group_req)) + goto e_inval; + retv = -EFAULT; if (copy_from_user(&greq, optval, sizeof(struct group_req))) break; @@ -615,7 +621,7 @@ done: struct group_source_req greqs; int omode, add; - if (optlen != sizeof(struct group_source_req)) + if (optlen < sizeof(struct group_source_req)) goto e_inval; if (copy_from_user(&greqs, optval, sizeof(greqs))) { retv = -EFAULT;