diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/datagram.c | 5 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 12 | ||||
-rw-r--r-- | net/ipv6/raw.c | 4 | ||||
-rw-r--r-- | net/ipv6/route.c | 8 |
4 files changed, 21 insertions, 8 deletions
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index b9c2de84a8a2..0f0f94a40335 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -705,6 +705,11 @@ int datagram_send_ctl(struct net *net, | |||
705 | } | 705 | } |
706 | 706 | ||
707 | *hlimit = *(int *)CMSG_DATA(cmsg); | 707 | *hlimit = *(int *)CMSG_DATA(cmsg); |
708 | if (*hlimit < -1 || *hlimit > 0xff) { | ||
709 | err = -EINVAL; | ||
710 | goto exit_f; | ||
711 | } | ||
712 | |||
708 | break; | 713 | break; |
709 | 714 | ||
710 | case IPV6_TCLASS: | 715 | case IPV6_TCLASS: |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 26b83e512a09..c042ce19bd14 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -67,7 +67,7 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *)) | |||
67 | 67 | ||
68 | /* RA packet may be delivered ONLY to IPPROTO_RAW socket */ | 68 | /* RA packet may be delivered ONLY to IPPROTO_RAW socket */ |
69 | if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num != IPPROTO_RAW) | 69 | if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num != IPPROTO_RAW) |
70 | return -EINVAL; | 70 | return -ENOPROTOOPT; |
71 | 71 | ||
72 | new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; | 72 | new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; |
73 | 73 | ||
@@ -446,7 +446,7 @@ done: | |||
446 | 446 | ||
447 | case IPV6_MULTICAST_HOPS: | 447 | case IPV6_MULTICAST_HOPS: |
448 | if (sk->sk_type == SOCK_STREAM) | 448 | if (sk->sk_type == SOCK_STREAM) |
449 | goto e_inval; | 449 | break; |
450 | if (optlen < sizeof(int)) | 450 | if (optlen < sizeof(int)) |
451 | goto e_inval; | 451 | goto e_inval; |
452 | if (val > 255 || val < -1) | 452 | if (val > 255 || val < -1) |
@@ -458,13 +458,15 @@ done: | |||
458 | case IPV6_MULTICAST_LOOP: | 458 | case IPV6_MULTICAST_LOOP: |
459 | if (optlen < sizeof(int)) | 459 | if (optlen < sizeof(int)) |
460 | goto e_inval; | 460 | goto e_inval; |
461 | if (val != valbool) | ||
462 | goto e_inval; | ||
461 | np->mc_loop = valbool; | 463 | np->mc_loop = valbool; |
462 | retv = 0; | 464 | retv = 0; |
463 | break; | 465 | break; |
464 | 466 | ||
465 | case IPV6_MULTICAST_IF: | 467 | case IPV6_MULTICAST_IF: |
466 | if (sk->sk_type == SOCK_STREAM) | 468 | if (sk->sk_type == SOCK_STREAM) |
467 | goto e_inval; | 469 | break; |
468 | if (optlen < sizeof(int)) | 470 | if (optlen < sizeof(int)) |
469 | goto e_inval; | 471 | goto e_inval; |
470 | 472 | ||
@@ -860,7 +862,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
860 | if (sk->sk_protocol != IPPROTO_UDP && | 862 | if (sk->sk_protocol != IPPROTO_UDP && |
861 | sk->sk_protocol != IPPROTO_UDPLITE && | 863 | sk->sk_protocol != IPPROTO_UDPLITE && |
862 | sk->sk_protocol != IPPROTO_TCP) | 864 | sk->sk_protocol != IPPROTO_TCP) |
863 | return -EINVAL; | 865 | return -ENOPROTOOPT; |
864 | if (sk->sk_state != TCP_ESTABLISHED) | 866 | if (sk->sk_state != TCP_ESTABLISHED) |
865 | return -ENOTCONN; | 867 | return -ENOTCONN; |
866 | val = sk->sk_family; | 868 | val = sk->sk_family; |
@@ -874,6 +876,8 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
874 | return -EINVAL; | 876 | return -EINVAL; |
875 | if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) | 877 | if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) |
876 | return -EFAULT; | 878 | return -EFAULT; |
879 | if (gsf.gf_group.ss_family != AF_INET6) | ||
880 | return -EADDRNOTAVAIL; | ||
877 | lock_sock(sk); | 881 | lock_sock(sk); |
878 | err = ip6_mc_msfget(sk, &gsf, | 882 | err = ip6_mc_msfget(sk, &gsf, |
879 | (struct group_filter __user *)optval, optlen); | 883 | (struct group_filter __user *)optval, optlen); |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 8fee9a15b2d3..3aee12310d94 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -1169,7 +1169,8 @@ static int raw6_destroy(struct sock *sk) | |||
1169 | lock_sock(sk); | 1169 | lock_sock(sk); |
1170 | ip6_flush_pending_frames(sk); | 1170 | ip6_flush_pending_frames(sk); |
1171 | release_sock(sk); | 1171 | release_sock(sk); |
1172 | return 0; | 1172 | |
1173 | return inet6_destroy_sock(sk); | ||
1173 | } | 1174 | } |
1174 | 1175 | ||
1175 | static int rawv6_init_sk(struct sock *sk) | 1176 | static int rawv6_init_sk(struct sock *sk) |
@@ -1200,7 +1201,6 @@ struct proto rawv6_prot = { | |||
1200 | .disconnect = udp_disconnect, | 1201 | .disconnect = udp_disconnect, |
1201 | .ioctl = rawv6_ioctl, | 1202 | .ioctl = rawv6_ioctl, |
1202 | .init = rawv6_init_sk, | 1203 | .init = rawv6_init_sk, |
1203 | .destroy = inet6_destroy_sock, | ||
1204 | .setsockopt = rawv6_setsockopt, | 1204 | .setsockopt = rawv6_setsockopt, |
1205 | .getsockopt = rawv6_getsockopt, | 1205 | .getsockopt = rawv6_getsockopt, |
1206 | .sendmsg = rawv6_sendmsg, | 1206 | .sendmsg = rawv6_sendmsg, |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 220cffe9e63b..d1f3e19b06c7 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -2196,8 +2196,12 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | |||
2196 | 2196 | ||
2197 | NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); | 2197 | NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); |
2198 | 2198 | ||
2199 | expires = (rt->rt6i_flags & RTF_EXPIRES) ? | 2199 | if (!(rt->rt6i_flags & RTF_EXPIRES)) |
2200 | rt->rt6i_expires - jiffies : 0; | 2200 | expires = 0; |
2201 | else if (rt->rt6i_expires - jiffies < INT_MAX) | ||
2202 | expires = rt->rt6i_expires - jiffies; | ||
2203 | else | ||
2204 | expires = INT_MAX; | ||
2201 | 2205 | ||
2202 | if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, | 2206 | if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, |
2203 | expires, rt->u.dst.error) < 0) | 2207 | expires, rt->u.dst.error) < 0) |