.. | .. |
---|
660 | 660 | |
---|
661 | 661 | void skb_release_head_state(struct sk_buff *skb) |
---|
662 | 662 | { |
---|
663 | | - nf_reset_ct(skb); |
---|
664 | 663 | skb_dst_drop(skb); |
---|
665 | 664 | if (skb->destructor) { |
---|
666 | 665 | WARN_ON(in_irq()); |
---|
.. | .. |
---|
2148 | 2147 | insp = list; |
---|
2149 | 2148 | } else { |
---|
2150 | 2149 | /* Eaten partially. */ |
---|
| 2150 | + if (skb_is_gso(skb) && !list->head_frag && |
---|
| 2151 | + skb_headlen(list)) |
---|
| 2152 | + skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; |
---|
2151 | 2153 | |
---|
2152 | 2154 | if (skb_shared(list)) { |
---|
2153 | 2155 | /* Sucks! We need to fork list. :-( */ |
---|
.. | .. |
---|
3704 | 3706 | |
---|
3705 | 3707 | skb_push(skb, -skb_network_offset(skb) + offset); |
---|
3706 | 3708 | |
---|
| 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 | + |
---|
3707 | 3714 | skb_shinfo(skb)->frag_list = NULL; |
---|
3708 | 3715 | |
---|
3709 | | - do { |
---|
| 3716 | + while (list_skb) { |
---|
3710 | 3717 | nskb = list_skb; |
---|
3711 | 3718 | list_skb = list_skb->next; |
---|
3712 | 3719 | |
---|
.. | .. |
---|
3752 | 3759 | if (skb_needs_linearize(nskb, features) && |
---|
3753 | 3760 | __skb_linearize(nskb)) |
---|
3754 | 3761 | goto err_linearize; |
---|
3755 | | - |
---|
3756 | | - } while (list_skb); |
---|
| 3762 | + } |
---|
3757 | 3763 | |
---|
3758 | 3764 | skb->truesize = skb->truesize - delta_truesize; |
---|
3759 | 3765 | skb->data_len = skb->data_len - delta_len; |
---|
.. | .. |
---|
3816 | 3822 | struct sk_buff *segs = NULL; |
---|
3817 | 3823 | struct sk_buff *tail = NULL; |
---|
3818 | 3824 | struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list; |
---|
3819 | | - skb_frag_t *frag = skb_shinfo(head_skb)->frags; |
---|
3820 | 3825 | unsigned int mss = skb_shinfo(head_skb)->gso_size; |
---|
3821 | 3826 | unsigned int doffset = head_skb->data - skb_mac_header(head_skb); |
---|
3822 | | - struct sk_buff *frag_skb = head_skb; |
---|
3823 | 3827 | unsigned int offset = doffset; |
---|
3824 | 3828 | unsigned int tnl_hlen = skb_tnl_header_len(head_skb); |
---|
3825 | 3829 | unsigned int partial_segs = 0; |
---|
3826 | 3830 | unsigned int headroom; |
---|
3827 | 3831 | unsigned int len = head_skb->len; |
---|
| 3832 | + struct sk_buff *frag_skb; |
---|
| 3833 | + skb_frag_t *frag; |
---|
3828 | 3834 | __be16 proto; |
---|
3829 | 3835 | bool csum, sg; |
---|
3830 | | - int nfrags = skb_shinfo(head_skb)->nr_frags; |
---|
3831 | 3836 | int err = -ENOMEM; |
---|
3832 | 3837 | int i = 0; |
---|
3833 | | - int pos; |
---|
| 3838 | + int nfrags, pos; |
---|
3834 | 3839 | |
---|
3835 | 3840 | if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) && |
---|
3836 | 3841 | mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) { |
---|
.. | .. |
---|
3907 | 3912 | headroom = skb_headroom(head_skb); |
---|
3908 | 3913 | pos = skb_headlen(head_skb); |
---|
3909 | 3914 | |
---|
| 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 | + |
---|
3910 | 3922 | do { |
---|
3911 | 3923 | struct sk_buff *nskb; |
---|
3912 | 3924 | skb_frag_t *nskb_frag; |
---|
.. | .. |
---|
3931 | 3943 | (skb_headlen(list_skb) == len || sg)) { |
---|
3932 | 3944 | BUG_ON(skb_headlen(list_skb) > len); |
---|
3933 | 3945 | |
---|
| 3946 | + nskb = skb_clone(list_skb, GFP_ATOMIC); |
---|
| 3947 | + if (unlikely(!nskb)) |
---|
| 3948 | + goto err; |
---|
| 3949 | + |
---|
3934 | 3950 | i = 0; |
---|
3935 | 3951 | nfrags = skb_shinfo(list_skb)->nr_frags; |
---|
3936 | 3952 | frag = skb_shinfo(list_skb)->frags; |
---|
.. | .. |
---|
3949 | 3965 | frag++; |
---|
3950 | 3966 | } |
---|
3951 | 3967 | |
---|
3952 | | - nskb = skb_clone(list_skb, GFP_ATOMIC); |
---|
3953 | 3968 | list_skb = list_skb->next; |
---|
3954 | | - |
---|
3955 | | - if (unlikely(!nskb)) |
---|
3956 | | - goto err; |
---|
3957 | 3969 | |
---|
3958 | 3970 | if (unlikely(pskb_trim(nskb, len))) { |
---|
3959 | 3971 | kfree_skb(nskb); |
---|
.. | .. |
---|
4025 | 4037 | skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags & |
---|
4026 | 4038 | SKBTX_SHARED_FRAG; |
---|
4027 | 4039 | |
---|
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)) |
---|
4030 | 4041 | goto err; |
---|
4031 | 4042 | |
---|
4032 | 4043 | while (pos < offset + len) { |
---|
4033 | 4044 | 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 | + |
---|
4034 | 4050 | i = 0; |
---|
4035 | 4051 | nfrags = skb_shinfo(list_skb)->nr_frags; |
---|
4036 | 4052 | frag = skb_shinfo(list_skb)->frags; |
---|
.. | .. |
---|
4044 | 4060 | i--; |
---|
4045 | 4061 | frag--; |
---|
4046 | 4062 | } |
---|
4047 | | - if (skb_orphan_frags(frag_skb, GFP_ATOMIC) || |
---|
4048 | | - skb_zerocopy_clone(nskb, frag_skb, |
---|
4049 | | - GFP_ATOMIC)) |
---|
4050 | | - goto err; |
---|
4051 | 4063 | |
---|
4052 | 4064 | list_skb = list_skb->next; |
---|
4053 | 4065 | } |
---|
.. | .. |
---|
4281 | 4293 | #if IS_ENABLED(CONFIG_MPTCP) |
---|
4282 | 4294 | [SKB_EXT_MPTCP] = SKB_EXT_CHUNKSIZEOF(struct mptcp_ext), |
---|
4283 | 4295 | #endif |
---|
4284 | | -#if IS_ENABLED(CONFIG_KCOV) |
---|
4285 | | - [SKB_EXT_KCOV_HANDLE] = SKB_EXT_CHUNKSIZEOF(u64), |
---|
4286 | | -#endif |
---|
4287 | 4296 | }; |
---|
4288 | 4297 | |
---|
4289 | 4298 | static __always_inline unsigned int skb_ext_total_length(void) |
---|
.. | .. |
---|
4300 | 4309 | #endif |
---|
4301 | 4310 | #if IS_ENABLED(CONFIG_MPTCP) |
---|
4302 | 4311 | skb_ext_type_len[SKB_EXT_MPTCP] + |
---|
4303 | | -#endif |
---|
4304 | | -#if IS_ENABLED(CONFIG_KCOV) |
---|
4305 | | - skb_ext_type_len[SKB_EXT_KCOV_HANDLE] + |
---|
4306 | 4312 | #endif |
---|
4307 | 4313 | 0; |
---|
4308 | 4314 | } |
---|
.. | .. |
---|
4778 | 4784 | skb = alloc_skb(0, GFP_ATOMIC); |
---|
4779 | 4785 | } else { |
---|
4780 | 4786 | skb = skb_clone(orig_skb, GFP_ATOMIC); |
---|
| 4787 | + |
---|
| 4788 | + if (skb_orphan_frags_rx(skb, GFP_ATOMIC)) { |
---|
| 4789 | + kfree_skb(skb); |
---|
| 4790 | + return; |
---|
| 4791 | + } |
---|
4781 | 4792 | } |
---|
4782 | 4793 | if (!skb) |
---|
4783 | 4794 | return; |
---|