diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2020-04-27 01:56:22 +0200 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2020-05-21 02:31:30 +0200 |
commit | 2f984f11fdc06bcfd5bb528d07a93c20301dd068 (patch) | |
tree | 6d0e66c255ae338b042aa173dc97b7f5bf4e0083 /net/ipv6 | |
parent | ipv6: do compat setsockopt for MCAST_MSFILTER directly (diff) | |
download | linux-2f984f11fdc06bcfd5bb528d07a93c20301dd068.tar.xz linux-2f984f11fdc06bcfd5bb528d07a93c20301dd068.zip |
ipv[46]: do compat setsockopt for MCAST_{JOIN,LEAVE}_GROUP directly
direct parallel to the way these two are handled in the native
->setsockopt() instances - the helpers that do the real work
are already separated and can be reused as-is in this case.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 2b5029df8f1e..209d827950cc 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -976,6 +976,34 @@ int compat_ipv6_setsockopt(struct sock *sk, int level, int optname, switch (optname) { case MCAST_JOIN_GROUP: case MCAST_LEAVE_GROUP: + { + struct compat_group_req __user *gr32 = (void __user *)optval; + struct group_req greq; + struct sockaddr_in6 *psin6 = (struct sockaddr_in6 *)&greq.gr_group; + + if (optlen < sizeof(struct compat_group_req)) + return -EINVAL; + + if (get_user(greq.gr_interface, &gr32->gr_interface) || + copy_from_user(&greq.gr_group, &gr32->gr_group, + sizeof(greq.gr_group))) + return -EFAULT; + + if (greq.gr_group.ss_family != AF_INET6) + return -EADDRNOTAVAIL; + + rtnl_lock(); + lock_sock(sk); + if (optname == MCAST_JOIN_GROUP) + err = ipv6_sock_mc_join(sk, greq.gr_interface, + &psin6->sin6_addr); + else + err = ipv6_sock_mc_drop(sk, greq.gr_interface, + &psin6->sin6_addr); + release_sock(sk); + rtnl_unlock(); + return err; + } case MCAST_JOIN_SOURCE_GROUP: case MCAST_LEAVE_SOURCE_GROUP: case MCAST_BLOCK_SOURCE: |