hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/dccp/ipv6.c
....@@ -67,7 +67,7 @@
6767 static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
6868 u8 type, u8 code, int offset, __be32 info)
6969 {
70
- const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
70
+ const struct ipv6hdr *hdr;
7171 const struct dccp_hdr *dh;
7272 struct dccp_sock *dp;
7373 struct ipv6_pinfo *np;
....@@ -76,12 +76,12 @@
7676 __u64 seq;
7777 struct net *net = dev_net(skb->dev);
7878
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;
8585 dh = (struct dccp_hdr *)(skb->data + offset);
8686
8787 sk = __inet6_lookup_established(net, &dccp_hashinfo,
....@@ -541,11 +541,9 @@
541541 *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), NULL);
542542 /* Clone pktoptions received with SYN, if we own the req */
543543 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);
545545 consume_skb(ireq->pktopts);
546546 ireq->pktopts = NULL;
547
- if (newnp->pktoptions)
548
- skb_set_owner_r(newnp->pktoptions, newsk);
549547 }
550548
551549 return newsk;
....@@ -605,7 +603,7 @@
605603 --ANK (980728)
606604 */
607605 if (np->rxopt.all)
608
- opt_skb = skb_clone(skb, GFP_ATOMIC);
606
+ opt_skb = skb_clone_and_charge_r(skb, sk);
609607
610608 if (sk->sk_state == DCCP_OPEN) { /* Fast path */
611609 if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
....@@ -669,7 +667,6 @@
669667 np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb));
670668 if (ipv6_opt_accepted(sk, opt_skb,
671669 &DCCP_SKB_CB(opt_skb)->header.h6)) {
672
- skb_set_owner_r(opt_skb, sk);
673670 memmove(IP6CB(opt_skb),
674671 &DCCP_SKB_CB(opt_skb)->header.h6,
675672 sizeof(struct inet6_skb_parm));
....@@ -995,6 +992,12 @@
995992 .sockaddr_len = sizeof(struct sockaddr_in6),
996993 };
997994
995
+static void dccp_v6_sk_destruct(struct sock *sk)
996
+{
997
+ dccp_destruct_common(sk);
998
+ inet6_sock_destruct(sk);
999
+}
1000
+
9981001 /* NOTE: A lot of things set to zero explicitly by call to
9991002 * sk_alloc() so need not be done here.
10001003 */
....@@ -1007,15 +1010,10 @@
10071010 if (unlikely(!dccp_v6_ctl_sock_initialized))
10081011 dccp_v6_ctl_sock_initialized = 1;
10091012 inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
1013
+ sk->sk_destruct = dccp_v6_sk_destruct;
10101014 }
10111015
10121016 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);
10191017 }
10201018
10211019 static struct timewait_sock_ops dccp6_timewait_sock_ops = {
....@@ -1040,7 +1038,7 @@
10401038 .accept = inet_csk_accept,
10411039 .get_port = inet_csk_get_port,
10421040 .shutdown = dccp_shutdown,
1043
- .destroy = dccp_v6_destroy_sock,
1041
+ .destroy = dccp_destroy_sock,
10441042 .orphan_count = &dccp_orphan_count,
10451043 .max_header = MAX_DCCP_HEADER,
10461044 .obj_size = sizeof(struct dccp6_sock),