hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/core/skbuff.c
....@@ -660,7 +660,6 @@
660660
661661 void skb_release_head_state(struct sk_buff *skb)
662662 {
663
- nf_reset_ct(skb);
664663 skb_dst_drop(skb);
665664 if (skb->destructor) {
666665 WARN_ON(in_irq());
....@@ -2148,6 +2147,9 @@
21482147 insp = list;
21492148 } else {
21502149 /* Eaten partially. */
2150
+ if (skb_is_gso(skb) && !list->head_frag &&
2151
+ skb_headlen(list))
2152
+ skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
21512153
21522154 if (skb_shared(list)) {
21532155 /* Sucks! We need to fork list. :-( */
....@@ -3704,9 +3706,14 @@
37043706
37053707 skb_push(skb, -skb_network_offset(skb) + offset);
37063708
3709
+ /* Ensure the head is writeable before touching the shared info */
3710
+ err = skb_unclone(skb, GFP_ATOMIC);
3711
+ if (err)
3712
+ goto err_linearize;
3713
+
37073714 skb_shinfo(skb)->frag_list = NULL;
37083715
3709
- do {
3716
+ while (list_skb) {
37103717 nskb = list_skb;
37113718 list_skb = list_skb->next;
37123719
....@@ -3752,8 +3759,7 @@
37523759 if (skb_needs_linearize(nskb, features) &&
37533760 __skb_linearize(nskb))
37543761 goto err_linearize;
3755
-
3756
- } while (list_skb);
3762
+ }
37573763
37583764 skb->truesize = skb->truesize - delta_truesize;
37593765 skb->data_len = skb->data_len - delta_len;
....@@ -3816,21 +3822,20 @@
38163822 struct sk_buff *segs = NULL;
38173823 struct sk_buff *tail = NULL;
38183824 struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list;
3819
- skb_frag_t *frag = skb_shinfo(head_skb)->frags;
38203825 unsigned int mss = skb_shinfo(head_skb)->gso_size;
38213826 unsigned int doffset = head_skb->data - skb_mac_header(head_skb);
3822
- struct sk_buff *frag_skb = head_skb;
38233827 unsigned int offset = doffset;
38243828 unsigned int tnl_hlen = skb_tnl_header_len(head_skb);
38253829 unsigned int partial_segs = 0;
38263830 unsigned int headroom;
38273831 unsigned int len = head_skb->len;
3832
+ struct sk_buff *frag_skb;
3833
+ skb_frag_t *frag;
38283834 __be16 proto;
38293835 bool csum, sg;
3830
- int nfrags = skb_shinfo(head_skb)->nr_frags;
38313836 int err = -ENOMEM;
38323837 int i = 0;
3833
- int pos;
3838
+ int nfrags, pos;
38343839
38353840 if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) &&
38363841 mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) {
....@@ -3907,6 +3912,13 @@
39073912 headroom = skb_headroom(head_skb);
39083913 pos = skb_headlen(head_skb);
39093914
3915
+ if (skb_orphan_frags(head_skb, GFP_ATOMIC))
3916
+ return ERR_PTR(-ENOMEM);
3917
+
3918
+ nfrags = skb_shinfo(head_skb)->nr_frags;
3919
+ frag = skb_shinfo(head_skb)->frags;
3920
+ frag_skb = head_skb;
3921
+
39103922 do {
39113923 struct sk_buff *nskb;
39123924 skb_frag_t *nskb_frag;
....@@ -3931,6 +3943,10 @@
39313943 (skb_headlen(list_skb) == len || sg)) {
39323944 BUG_ON(skb_headlen(list_skb) > len);
39333945
3946
+ nskb = skb_clone(list_skb, GFP_ATOMIC);
3947
+ if (unlikely(!nskb))
3948
+ goto err;
3949
+
39343950 i = 0;
39353951 nfrags = skb_shinfo(list_skb)->nr_frags;
39363952 frag = skb_shinfo(list_skb)->frags;
....@@ -3949,11 +3965,7 @@
39493965 frag++;
39503966 }
39513967
3952
- nskb = skb_clone(list_skb, GFP_ATOMIC);
39533968 list_skb = list_skb->next;
3954
-
3955
- if (unlikely(!nskb))
3956
- goto err;
39573969
39583970 if (unlikely(pskb_trim(nskb, len))) {
39593971 kfree_skb(nskb);
....@@ -4025,12 +4037,16 @@
40254037 skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags &
40264038 SKBTX_SHARED_FRAG;
40274039
4028
- if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
4029
- skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
4040
+ if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
40304041 goto err;
40314042
40324043 while (pos < offset + len) {
40334044 if (i >= nfrags) {
4045
+ if (skb_orphan_frags(list_skb, GFP_ATOMIC) ||
4046
+ skb_zerocopy_clone(nskb, list_skb,
4047
+ GFP_ATOMIC))
4048
+ goto err;
4049
+
40344050 i = 0;
40354051 nfrags = skb_shinfo(list_skb)->nr_frags;
40364052 frag = skb_shinfo(list_skb)->frags;
....@@ -4044,10 +4060,6 @@
40444060 i--;
40454061 frag--;
40464062 }
4047
- if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
4048
- skb_zerocopy_clone(nskb, frag_skb,
4049
- GFP_ATOMIC))
4050
- goto err;
40514063
40524064 list_skb = list_skb->next;
40534065 }
....@@ -4281,9 +4293,6 @@
42814293 #if IS_ENABLED(CONFIG_MPTCP)
42824294 [SKB_EXT_MPTCP] = SKB_EXT_CHUNKSIZEOF(struct mptcp_ext),
42834295 #endif
4284
-#if IS_ENABLED(CONFIG_KCOV)
4285
- [SKB_EXT_KCOV_HANDLE] = SKB_EXT_CHUNKSIZEOF(u64),
4286
-#endif
42874296 };
42884297
42894298 static __always_inline unsigned int skb_ext_total_length(void)
....@@ -4300,9 +4309,6 @@
43004309 #endif
43014310 #if IS_ENABLED(CONFIG_MPTCP)
43024311 skb_ext_type_len[SKB_EXT_MPTCP] +
4303
-#endif
4304
-#if IS_ENABLED(CONFIG_KCOV)
4305
- skb_ext_type_len[SKB_EXT_KCOV_HANDLE] +
43064312 #endif
43074313 0;
43084314 }
....@@ -4778,6 +4784,11 @@
47784784 skb = alloc_skb(0, GFP_ATOMIC);
47794785 } else {
47804786 skb = skb_clone(orig_skb, GFP_ATOMIC);
4787
+
4788
+ if (skb_orphan_frags_rx(skb, GFP_ATOMIC)) {
4789
+ kfree_skb(skb);
4790
+ return;
4791
+ }
47814792 }
47824793 if (!skb)
47834794 return;