diff options
Diffstat (limited to 'net/ipv6/ipv6_sockglue.c')
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 237ebbb9383b..a9988841172a 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -65,7 +65,7 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *)) | |||
65 | 65 | ||
66 | /* RA packet may be delivered ONLY to IPPROTO_RAW socket */ | 66 | /* RA packet may be delivered ONLY to IPPROTO_RAW socket */ |
67 | if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num != IPPROTO_RAW) | 67 | if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num != IPPROTO_RAW) |
68 | return -EINVAL; | 68 | return -ENOPROTOOPT; |
69 | 69 | ||
70 | new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; | 70 | new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; |
71 | 71 | ||
@@ -444,7 +444,7 @@ done: | |||
444 | 444 | ||
445 | case IPV6_MULTICAST_HOPS: | 445 | case IPV6_MULTICAST_HOPS: |
446 | if (sk->sk_type == SOCK_STREAM) | 446 | if (sk->sk_type == SOCK_STREAM) |
447 | goto e_inval; | 447 | break; |
448 | if (optlen < sizeof(int)) | 448 | if (optlen < sizeof(int)) |
449 | goto e_inval; | 449 | goto e_inval; |
450 | if (val > 255 || val < -1) | 450 | if (val > 255 || val < -1) |
@@ -456,13 +456,15 @@ done: | |||
456 | case IPV6_MULTICAST_LOOP: | 456 | case IPV6_MULTICAST_LOOP: |
457 | if (optlen < sizeof(int)) | 457 | if (optlen < sizeof(int)) |
458 | goto e_inval; | 458 | goto e_inval; |
459 | if (val != valbool) | ||
460 | goto e_inval; | ||
459 | np->mc_loop = valbool; | 461 | np->mc_loop = valbool; |
460 | retv = 0; | 462 | retv = 0; |
461 | break; | 463 | break; |
462 | 464 | ||
463 | case IPV6_MULTICAST_IF: | 465 | case IPV6_MULTICAST_IF: |
464 | if (sk->sk_type == SOCK_STREAM) | 466 | if (sk->sk_type == SOCK_STREAM) |
465 | goto e_inval; | 467 | break; |
466 | if (optlen < sizeof(int)) | 468 | if (optlen < sizeof(int)) |
467 | goto e_inval; | 469 | goto e_inval; |
468 | 470 | ||
@@ -858,7 +860,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
858 | if (sk->sk_protocol != IPPROTO_UDP && | 860 | if (sk->sk_protocol != IPPROTO_UDP && |
859 | sk->sk_protocol != IPPROTO_UDPLITE && | 861 | sk->sk_protocol != IPPROTO_UDPLITE && |
860 | sk->sk_protocol != IPPROTO_TCP) | 862 | sk->sk_protocol != IPPROTO_TCP) |
861 | return -EINVAL; | 863 | return -ENOPROTOOPT; |
862 | if (sk->sk_state != TCP_ESTABLISHED) | 864 | if (sk->sk_state != TCP_ESTABLISHED) |
863 | return -ENOTCONN; | 865 | return -ENOTCONN; |
864 | val = sk->sk_family; | 866 | val = sk->sk_family; |
@@ -872,6 +874,8 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
872 | return -EINVAL; | 874 | return -EINVAL; |
873 | if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) | 875 | if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) |
874 | return -EFAULT; | 876 | return -EFAULT; |
877 | if (gsf.gf_group.ss_family != AF_INET6) | ||
878 | return -EADDRNOTAVAIL; | ||
875 | lock_sock(sk); | 879 | lock_sock(sk); |
876 | err = ip6_mc_msfget(sk, &gsf, | 880 | err = ip6_mc_msfget(sk, &gsf, |
877 | (struct group_filter __user *)optval, optlen); | 881 | (struct group_filter __user *)optval, optlen); |