.. | .. |
---|
67 | 67 | static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
---|
68 | 68 | u8 type, u8 code, int offset, __be32 info) |
---|
69 | 69 | { |
---|
70 | | - const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; |
---|
| 70 | + const struct ipv6hdr *hdr; |
---|
71 | 71 | const struct dccp_hdr *dh; |
---|
72 | 72 | struct dccp_sock *dp; |
---|
73 | 73 | struct ipv6_pinfo *np; |
---|
.. | .. |
---|
76 | 76 | __u64 seq; |
---|
77 | 77 | struct net *net = dev_net(skb->dev); |
---|
78 | 78 | |
---|
79 | | - /* Only need dccph_dport & dccph_sport which are the first |
---|
80 | | - * 4 bytes in dccp header. |
---|
81 | | - * Our caller (icmpv6_notify()) already pulled 8 bytes for us. |
---|
82 | | - */ |
---|
83 | | - BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8); |
---|
84 | | - BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8); |
---|
| 79 | + if (!pskb_may_pull(skb, offset + sizeof(*dh))) |
---|
| 80 | + return -EINVAL; |
---|
| 81 | + dh = (struct dccp_hdr *)(skb->data + offset); |
---|
| 82 | + if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) |
---|
| 83 | + return -EINVAL; |
---|
| 84 | + hdr = (const struct ipv6hdr *)skb->data; |
---|
85 | 85 | dh = (struct dccp_hdr *)(skb->data + offset); |
---|
86 | 86 | |
---|
87 | 87 | sk = __inet6_lookup_established(net, &dccp_hashinfo, |
---|
.. | .. |
---|
541 | 541 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), NULL); |
---|
542 | 542 | /* Clone pktoptions received with SYN, if we own the req */ |
---|
543 | 543 | if (*own_req && ireq->pktopts) { |
---|
544 | | - newnp->pktoptions = skb_clone(ireq->pktopts, GFP_ATOMIC); |
---|
| 544 | + newnp->pktoptions = skb_clone_and_charge_r(ireq->pktopts, newsk); |
---|
545 | 545 | consume_skb(ireq->pktopts); |
---|
546 | 546 | ireq->pktopts = NULL; |
---|
547 | | - if (newnp->pktoptions) |
---|
548 | | - skb_set_owner_r(newnp->pktoptions, newsk); |
---|
549 | 547 | } |
---|
550 | 548 | |
---|
551 | 549 | return newsk; |
---|
.. | .. |
---|
605 | 603 | --ANK (980728) |
---|
606 | 604 | */ |
---|
607 | 605 | if (np->rxopt.all) |
---|
608 | | - opt_skb = skb_clone(skb, GFP_ATOMIC); |
---|
| 606 | + opt_skb = skb_clone_and_charge_r(skb, sk); |
---|
609 | 607 | |
---|
610 | 608 | if (sk->sk_state == DCCP_OPEN) { /* Fast path */ |
---|
611 | 609 | if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len)) |
---|
.. | .. |
---|
669 | 667 | np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb)); |
---|
670 | 668 | if (ipv6_opt_accepted(sk, opt_skb, |
---|
671 | 669 | &DCCP_SKB_CB(opt_skb)->header.h6)) { |
---|
672 | | - skb_set_owner_r(opt_skb, sk); |
---|
673 | 670 | memmove(IP6CB(opt_skb), |
---|
674 | 671 | &DCCP_SKB_CB(opt_skb)->header.h6, |
---|
675 | 672 | sizeof(struct inet6_skb_parm)); |
---|
.. | .. |
---|
995 | 992 | .sockaddr_len = sizeof(struct sockaddr_in6), |
---|
996 | 993 | }; |
---|
997 | 994 | |
---|
| 995 | +static void dccp_v6_sk_destruct(struct sock *sk) |
---|
| 996 | +{ |
---|
| 997 | + dccp_destruct_common(sk); |
---|
| 998 | + inet6_sock_destruct(sk); |
---|
| 999 | +} |
---|
| 1000 | + |
---|
998 | 1001 | /* NOTE: A lot of things set to zero explicitly by call to |
---|
999 | 1002 | * sk_alloc() so need not be done here. |
---|
1000 | 1003 | */ |
---|
.. | .. |
---|
1007 | 1010 | if (unlikely(!dccp_v6_ctl_sock_initialized)) |
---|
1008 | 1011 | dccp_v6_ctl_sock_initialized = 1; |
---|
1009 | 1012 | inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops; |
---|
| 1013 | + sk->sk_destruct = dccp_v6_sk_destruct; |
---|
1010 | 1014 | } |
---|
1011 | 1015 | |
---|
1012 | 1016 | return err; |
---|
1013 | | -} |
---|
1014 | | - |
---|
1015 | | -static void dccp_v6_destroy_sock(struct sock *sk) |
---|
1016 | | -{ |
---|
1017 | | - dccp_destroy_sock(sk); |
---|
1018 | | - inet6_destroy_sock(sk); |
---|
1019 | 1017 | } |
---|
1020 | 1018 | |
---|
1021 | 1019 | static struct timewait_sock_ops dccp6_timewait_sock_ops = { |
---|
.. | .. |
---|
1040 | 1038 | .accept = inet_csk_accept, |
---|
1041 | 1039 | .get_port = inet_csk_get_port, |
---|
1042 | 1040 | .shutdown = dccp_shutdown, |
---|
1043 | | - .destroy = dccp_v6_destroy_sock, |
---|
| 1041 | + .destroy = dccp_destroy_sock, |
---|
1044 | 1042 | .orphan_count = &dccp_orphan_count, |
---|
1045 | 1043 | .max_header = MAX_DCCP_HEADER, |
---|
1046 | 1044 | .obj_size = sizeof(struct dccp6_sock), |
---|