| .. | .. |
|---|
| 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), |
|---|