Commit be666e0a authored by David L Stevens's avatar David L Stevens Committed by David S. Miller

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: default avatarDavid L Stevens <dlstevens@us.ibm.com>
Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2ad17def
...@@ -548,6 +548,9 @@ struct compat_group_filter { ...@@ -548,6 +548,9 @@ struct compat_group_filter {
__attribute__ ((aligned(4))); __attribute__ ((aligned(4)));
} __attribute__ ((packed)); } __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, int compat_mc_setsockopt(struct sock *sock, int level, int optname,
char __user *optval, int optlen, char __user *optval, int optlen,
...@@ -582,7 +585,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, ...@@ -582,7 +585,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
case MCAST_UNBLOCK_SOURCE: case MCAST_UNBLOCK_SOURCE:
{ {
struct compat_group_source_req __user *gsr32 = (void *)optval; 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)); sizeof(struct group_source_req));
u32 interface; u32 interface;
...@@ -603,10 +606,10 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, ...@@ -603,10 +606,10 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
case MCAST_MSFILTER: case MCAST_MSFILTER:
{ {
struct compat_group_filter __user *gf32 = (void *)optval; struct compat_group_filter __user *gf32 = (void *)optval;
struct group_filter *kgf; struct group_filter __user *kgf;
u32 interface, fmode, numsrc; 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(interface, &gf32->gf_interface) ||
__get_user(fmode, &gf32->gf_fmode) || __get_user(fmode, &gf32->gf_fmode) ||
__get_user(numsrc, &gf32->gf_numsrc)) __get_user(numsrc, &gf32->gf_numsrc))
...@@ -622,7 +625,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, ...@@ -622,7 +625,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
__put_user(numsrc, &kgf->gf_numsrc) || __put_user(numsrc, &kgf->gf_numsrc) ||
copy_in_user(&kgf->gf_group, &gf32->gf_group, copy_in_user(&kgf->gf_group, &gf32->gf_group,
sizeof(kgf->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])))) numsrc * sizeof(kgf->gf_slist[0]))))
return -EFAULT; return -EFAULT;
koptval = (char __user *)kgf; koptval = (char __user *)kgf;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment