diff options
author | David L Stevens <dlstevens@us.ibm.com> | 2008-04-29 03:23:00 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-29 03:23:00 -0700 |
commit | be666e0a1345ed80f29cb30c73da0ec2ea5c5863 (patch) | |
tree | 46a29aa49e2357a3c1c69a39d9789a16c568fe9d | |
parent | 2ad17defd596ca7e8ba782d5fc6950ee0e99513c (diff) | |
download | linux-be666e0a1345ed80f29cb30c73da0ec2ea5c5863.tar.bz2 |
net: Several cleanups for the setsockopt compat support.
1) added missing "__user" for kgsr and kgf pointers
2) verify read for only GROUP_FILTER_SIZE(0). The group_filter
structure definition (via RFC) includes space for one source
in the source list array, but that source need not be present.
So, sizeof(group_filter) > GROUP_FILTER_SIZE(0). Fixed
the user read-check for minimum length to use the smaller size.
3) remove unneeded "&" for gf_slist addresses
Signed-off-by: David L Stevens <dlstevens@us.ibm.com>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/compat.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/net/compat.c b/net/compat.c index 01bf95d0832e..8146f654391c 100644 --- a/net/compat.c +++ b/net/compat.c @@ -548,6 +548,9 @@ struct compat_group_filter { __attribute__ ((aligned(4))); } __attribute__ ((packed)); +#define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \ + sizeof(struct __kernel_sockaddr_storage)) + int compat_mc_setsockopt(struct sock *sock, int level, int optname, char __user *optval, int optlen, @@ -582,7 +585,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, case MCAST_UNBLOCK_SOURCE: { struct compat_group_source_req __user *gsr32 = (void *)optval; - struct group_source_req *kgsr = compat_alloc_user_space( + struct group_source_req __user *kgsr = compat_alloc_user_space( sizeof(struct group_source_req)); u32 interface; @@ -603,10 +606,10 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, case MCAST_MSFILTER: { struct compat_group_filter __user *gf32 = (void *)optval; - struct group_filter *kgf; + struct group_filter __user *kgf; u32 interface, fmode, numsrc; - if (!access_ok(VERIFY_READ, gf32, sizeof(*gf32)) || + if (!access_ok(VERIFY_READ, gf32, __COMPAT_GF0_SIZE) || __get_user(interface, &gf32->gf_interface) || __get_user(fmode, &gf32->gf_fmode) || __get_user(numsrc, &gf32->gf_numsrc)) @@ -622,7 +625,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, __put_user(numsrc, &kgf->gf_numsrc) || copy_in_user(&kgf->gf_group, &gf32->gf_group, sizeof(kgf->gf_group)) || - (numsrc && copy_in_user(&kgf->gf_slist, &gf32->gf_slist, + (numsrc && copy_in_user(kgf->gf_slist, gf32->gf_slist, numsrc * sizeof(kgf->gf_slist[0])))) return -EFAULT; koptval = (char __user *)kgf; |