[IPV6]: Check length of optval provided by user in setsockopt().
authorWang Chen <wangchen@cn.fujitsu.com>
Mon, 7 Apr 2008 01:42:07 +0000 (09:42 +0800)
committerYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Sat, 12 Apr 2008 04:43:23 +0000 (13:43 +0900)
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.

Signed-off-by: Wang Chen <wangchen@cn.fujitsu.com>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
net/ipv6/ipv6_sockglue.c

index bf96953..bd3fb12 100644 (file)
@@ -449,6 +449,9 @@ done:
        {
                struct ipv6_mreq mreq;
 
+               if (optlen < sizeof(struct ipv6_mreq))
+                       goto e_inval;
+
                retv = -EPROTO;
                if (inet_sk(sk)->is_icsk)
                        break;
@@ -468,7 +471,7 @@ done:
        {
                struct ipv6_mreq mreq;
 
-               if (optlen != sizeof(struct ipv6_mreq))
+               if (optlen < sizeof(struct ipv6_mreq))
                        goto e_inval;
 
                retv = -EFAULT;
@@ -487,6 +490,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;
@@ -511,7 +517,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;