aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ipv6_sockglue.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ipv6_sockglue.c')
-rw-r--r--net/ipv6/ipv6_sockglue.c12
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);