Re: [PATCH net 1/1] net: skbuff: reject skb header offset updates that truncate
kernel test robot <[email protected]> Fri, 31 Jul 2026 02:48:14 +0800
| Newsgroups | dev.linux.lists.oe-kbuild |
|---|---|
| Message-ID | <[email protected]> |
BCC: [email protected] CC: [email protected] In-Reply-To: <06ac032651d91cfe4b2e246f6fc36e3d4b2f87d1.1785346409.git.zihanx@nebusec.ai> References: <06ac032651d91cfe4b2e246f6fc36e3d4b2f87d1.1785346409.git.zihanx@nebusec.ai> TO: Zihan Xi <[email protected]> TO: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] CC: [email protected] Hi Zihan, kernel test robot noticed the following build warnings: [auto build test WARNING on net/main] url: https://github.com/intel-lab-lkp/linux/commits/Zihan-Xi/net-skbuff-reject-skb-header-offset-updates-that-truncate/20260730-175139 base: net/main patch link: https://lore.kernel.org/r/06ac032651d91cfe4b2e246f6fc36e3d4b2f87d1.1785346409.git.zihanx%40nebusec.ai patch subject: [PATCH net 1/1] net: skbuff: reject skb header offset updates that truncate :::::: branch date: 11 hours ago :::::: commit date: 11 hours ago config: i386-randconfig-141-20260730 (https://download.01.org/0day-ci/archive/20260731/[email protected]/config) compiler: gcc-14 (Debian 14.2.0-19) 14.2.0 smatch: v0.5.0-9187-g5189e3fb If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <[email protected]> | Reported-by: Dan Carpenter <[email protected]> | Closes: https://lore.kernel.org/r/[email protected]/ New smatch warnings: net/core/skbuff.c:5208 skb_segment() warn: passing zero to 'ERR_PTR' Old smatch warnings: net/core/skbuff.c:4975 skb_segment() error: we previously assumed 'list_skb' could be null (see line 4910) vim +/ERR_PTR +5208 net/core/skbuff.c 3a1296a38d0cf62 Steffen Klassert 2020-01-25 4845 f4c50d990dcf11a Herbert Xu 2006-06-22 4846 /** f4c50d990dcf11a Herbert Xu 2006-06-22 4847 * skb_segment - Perform protocol segmentation on skb. df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 4848 * @head_skb: buffer to segment 576a30eb6453439 Herbert Xu 2006-06-27 4849 * @features: features for the output path (see dev->features) f4c50d990dcf11a Herbert Xu 2006-06-22 4850 * f4c50d990dcf11a Herbert Xu 2006-06-22 4851 * This function performs segmentation on the given skb. It returns 4c821d753d5c097 Ben Hutchings 2008-04-13 4852 * a pointer to the first in a list of new skbs for the segments. 4c821d753d5c097 Ben Hutchings 2008-04-13 4853 * In case of error it returns ERR_PTR(err). f4c50d990dcf11a Herbert Xu 2006-06-22 4854 */ df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 4855 struct sk_buff *skb_segment(struct sk_buff *head_skb, df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 4856 netdev_features_t features) f4c50d990dcf11a Herbert Xu 2006-06-22 4857 { f4c50d990dcf11a Herbert Xu 2006-06-22 4858 struct sk_buff *segs = NULL; f4c50d990dcf11a Herbert Xu 2006-06-22 4859 struct sk_buff *tail = NULL; 1a4cedaf65491e6 Michael S. Tsirkin 2014-03-10 4860 struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list; df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 4861 unsigned int mss = skb_shinfo(head_skb)->gso_size; df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 4862 unsigned int doffset = head_skb->data - skb_mac_header(head_skb); f4c50d990dcf11a Herbert Xu 2006-06-22 4863 unsigned int offset = doffset; df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 4864 unsigned int tnl_hlen = skb_tnl_header_len(head_skb); 802ab55adc39a06 Alexander Duyck 2016-04-10 4865 unsigned int partial_segs = 0; f4c50d990dcf11a Herbert Xu 2006-06-22 4866 unsigned int headroom; 802ab55adc39a06 Alexander Duyck 2016-04-10 4867 unsigned int len = head_skb->len; 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4868 struct sk_buff *frag_skb; 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4869 skb_frag_t *frag; ec5f06156423889 Pravin B Shelar 2013-03-07 4870 __be16 proto; 36c983824b6f17b Alexander Duyck 2016-05-02 4871 bool csum, sg; f4c50d990dcf11a Herbert Xu 2006-06-22 4872 int err = -ENOMEM; f4c50d990dcf11a Herbert Xu 2006-06-22 4873 int i = 0; 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4874 int nfrags, pos; f4c50d990dcf11a Herbert Xu 2006-06-22 4875 9e4b7a99a03aefd Jiri Benc 2022-11-02 4876 if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) && 9e4b7a99a03aefd Jiri Benc 2022-11-02 4877 mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) { 9e4b7a99a03aefd Jiri Benc 2022-11-02 4878 struct sk_buff *check_skb; 9e4b7a99a03aefd Jiri Benc 2022-11-02 4879 9e4b7a99a03aefd Jiri Benc 2022-11-02 4880 for (check_skb = list_skb; check_skb; check_skb = check_skb->next) { 9e4b7a99a03aefd Jiri Benc 2022-11-02 4881 if (skb_headlen(check_skb) && !check_skb->head_frag) { 9e4b7a99a03aefd Jiri Benc 2022-11-02 4882 /* gso_size is untrusted, and we have a frag_list with 9e4b7a99a03aefd Jiri Benc 2022-11-02 4883 * a linear non head_frag item. 3dcbdb134f32984 Shmulik Ladkani 2019-09-06 4884 * 9e4b7a99a03aefd Jiri Benc 2022-11-02 4885 * If head_skb's headlen does not fit requested gso_size, 9e4b7a99a03aefd Jiri Benc 2022-11-02 4886 * it means that the frag_list members do NOT terminate 9e4b7a99a03aefd Jiri Benc 2022-11-02 4887 * on exact gso_size boundaries. Hence we cannot perform 9e4b7a99a03aefd Jiri Benc 2022-11-02 4888 * skb_frag_t page sharing. Therefore we must fallback to 9e4b7a99a03aefd Jiri Benc 2022-11-02 4889 * copying the frag_list skbs; we do so by disabling SG. 3dcbdb134f32984 Shmulik Ladkani 2019-09-06 4890 */ 3dcbdb134f32984 Shmulik Ladkani 2019-09-06 4891 features &= ~NETIF_F_SG; 9e4b7a99a03aefd Jiri Benc 2022-11-02 4892 break; 9e4b7a99a03aefd Jiri Benc 2022-11-02 4893 } 9e4b7a99a03aefd Jiri Benc 2022-11-02 4894 } 3dcbdb134f32984 Shmulik Ladkani 2019-09-06 4895 } 3dcbdb134f32984 Shmulik Ladkani 2019-09-06 4896 5882a07c72093dc Wei-Chun Chao 2014-06-08 4897 __skb_push(head_skb, doffset); 2f631133c40cd8e Miaohe Lin 2020-08-01 4898 proto = skb_network_protocol(head_skb, NULL); ec5f06156423889 Pravin B Shelar 2013-03-07 4899 if (unlikely(!proto)) ec5f06156423889 Pravin B Shelar 2013-03-07 4900 return ERR_PTR(-EINVAL); ec5f06156423889 Pravin B Shelar 2013-03-07 4901 36c983824b6f17b Alexander Duyck 2016-05-02 4902 sg = !!(features & NETIF_F_SG); f245d079c1d11dc Alexander Duyck 2016-02-05 4903 csum = !!can_checksum_protocol(features, proto); 7e2b10c1e52ca37 Tom Herbert 2014-06-04 4904 07b26c9454a2a19 Steffen Klassert 2016-09-19 4905 if (sg && csum && (mss != GSO_BY_FRAGS)) { 07b26c9454a2a19 Steffen Klassert 2016-09-19 4906 if (!(features & NETIF_F_GSO_PARTIAL)) { 07b26c9454a2a19 Steffen Klassert 2016-09-19 4907 struct sk_buff *iter; 43170c4e0ba709c Ilan Tayari 2017-04-19 4908 unsigned int frag_len; 07b26c9454a2a19 Steffen Klassert 2016-09-19 4909 07b26c9454a2a19 Steffen Klassert 2016-09-19 4910 if (!list_skb || 07b26c9454a2a19 Steffen Klassert 2016-09-19 4911 !net_gso_ok(features, skb_shinfo(head_skb)->gso_type)) 07b26c9454a2a19 Steffen Klassert 2016-09-19 4912 goto normal; 07b26c9454a2a19 Steffen Klassert 2016-09-19 4913 43170c4e0ba709c Ilan Tayari 2017-04-19 4914 /* If we get here then all the required 43170c4e0ba709c Ilan Tayari 2017-04-19 4915 * GSO features except frag_list are supported. 43170c4e0ba709c Ilan Tayari 2017-04-19 4916 * Try to split the SKB to multiple GSO SKBs 43170c4e0ba709c Ilan Tayari 2017-04-19 4917 * with no frag_list. 43170c4e0ba709c Ilan Tayari 2017-04-19 4918 * Currently we can do that only when the buffers don't 43170c4e0ba709c Ilan Tayari 2017-04-19 4919 * have a linear part and all the buffers except 43170c4e0ba709c Ilan Tayari 2017-04-19 4920 * the last are of the same length. 07b26c9454a2a19 Steffen Klassert 2016-09-19 4921 */ 43170c4e0ba709c Ilan Tayari 2017-04-19 4922 frag_len = list_skb->len; 07b26c9454a2a19 Steffen Klassert 2016-09-19 4923 skb_walk_frags(head_skb, iter) { 43170c4e0ba709c Ilan Tayari 2017-04-19 4924 if (frag_len != iter->len && iter->next) 43170c4e0ba709c Ilan Tayari 2017-04-19 4925 goto normal; eaffadbbb3f2711 Ilan Tayari 2017-04-08 4926 if (skb_headlen(iter) && !iter->head_frag) 07b26c9454a2a19 Steffen Klassert 2016-09-19 4927 goto normal; 07b26c9454a2a19 Steffen Klassert 2016-09-19 4928 07b26c9454a2a19 Steffen Klassert 2016-09-19 4929 len -= iter->len; 07b26c9454a2a19 Steffen Klassert 2016-09-19 4930 } 43170c4e0ba709c Ilan Tayari 2017-04-19 4931 43170c4e0ba709c Ilan Tayari 2017-04-19 4932 if (len != frag_len) 43170c4e0ba709c Ilan Tayari 2017-04-19 4933 goto normal; 07b26c9454a2a19 Steffen Klassert 2016-09-19 4934 } 07b26c9454a2a19 Steffen Klassert 2016-09-19 4935 802ab55adc39a06 Alexander Duyck 2016-04-10 4936 /* GSO partial only requires that we trim off any excess that 802ab55adc39a06 Alexander Duyck 2016-04-10 4937 * doesn't fit into an MSS sized block, so take care of that 802ab55adc39a06 Alexander Duyck 2016-04-10 4938 * now. 23d05d563b7e7b0 Eric Dumazet 2023-12-12 4939 * Cap len to not accidentally hit GSO_BY_FRAGS. 802ab55adc39a06 Alexander Duyck 2016-04-10 4940 */ 23d05d563b7e7b0 Eric Dumazet 2023-12-12 4941 partial_segs = min(len, GSO_BY_FRAGS - 1) / mss; d7fb5a80492169c Alexander Duyck 2016-05-02 4942 if (partial_segs > 1) 802ab55adc39a06 Alexander Duyck 2016-04-10 4943 mss *= partial_segs; d7fb5a80492169c Alexander Duyck 2016-05-02 4944 else d7fb5a80492169c Alexander Duyck 2016-05-02 4945 partial_segs = 0; 802ab55adc39a06 Alexander Duyck 2016-04-10 4946 } 802ab55adc39a06 Alexander Duyck 2016-04-10 4947 07b26c9454a2a19 Steffen Klassert 2016-09-19 4948 normal: df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 4949 headroom = skb_headroom(head_skb); df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 4950 pos = skb_headlen(head_skb); f4c50d990dcf11a Herbert Xu 2006-06-22 4951 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4952 if (skb_orphan_frags(head_skb, GFP_ATOMIC)) 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4953 return ERR_PTR(-ENOMEM); 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4954 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4955 nfrags = skb_shinfo(head_skb)->nr_frags; 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4956 frag = skb_shinfo(head_skb)->frags; 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4957 frag_skb = head_skb; 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4958 f4c50d990dcf11a Herbert Xu 2006-06-22 4959 do { f4c50d990dcf11a Herbert Xu 2006-06-22 4960 struct sk_buff *nskb; 8cb19905e9287a9 Michael S. Tsirkin 2014-03-10 4961 skb_frag_t *nskb_frag; c8884edd0787489 Herbert Xu 2006-10-29 4962 int hsize; f4c50d990dcf11a Herbert Xu 2006-06-22 4963 int size; f4c50d990dcf11a Herbert Xu 2006-06-22 4964 3953c46c3ac7eef Marcelo Ricardo Leitner 2016-06-02 4965 if (unlikely(mss == GSO_BY_FRAGS)) { 3953c46c3ac7eef Marcelo Ricardo Leitner 2016-06-02 4966 len = list_skb->len; 3953c46c3ac7eef Marcelo Ricardo Leitner 2016-06-02 4967 } else { df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 4968 len = head_skb->len - offset; f4c50d990dcf11a Herbert Xu 2006-06-22 4969 if (len > mss) f4c50d990dcf11a Herbert Xu 2006-06-22 4970 len = mss; 3953c46c3ac7eef Marcelo Ricardo Leitner 2016-06-02 4971 } f4c50d990dcf11a Herbert Xu 2006-06-22 4972 df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 4973 hsize = skb_headlen(head_skb) - offset; f4c50d990dcf11a Herbert Xu 2006-06-22 4974 dbd50f238decfe5 Xin Long 2021-01-15 4975 if (hsize <= 0 && i >= nfrags && skb_headlen(list_skb) && 1a4cedaf65491e6 Michael S. Tsirkin 2014-03-10 4976 (skb_headlen(list_skb) == len || sg)) { 1a4cedaf65491e6 Michael S. Tsirkin 2014-03-10 4977 BUG_ON(skb_headlen(list_skb) > len); 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4978 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4979 nskb = skb_clone(list_skb, GFP_ATOMIC); 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4980 if (unlikely(!nskb)) 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4981 goto err; 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 4982 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4983 i = 0; 1a4cedaf65491e6 Michael S. Tsirkin 2014-03-10 4984 nfrags = skb_shinfo(list_skb)->nr_frags; 1a4cedaf65491e6 Michael S. Tsirkin 2014-03-10 4985 frag = skb_shinfo(list_skb)->frags; 1fd819ecb90cc9b Michael S. Tsirkin 2014-03-10 4986 frag_skb = list_skb; 1a4cedaf65491e6 Michael S. Tsirkin 2014-03-10 4987 pos += skb_headlen(list_skb); 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4988 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4989 while (pos < offset + len) { 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4990 BUG_ON(i >= nfrags); 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4991 4e1beba12d094c6 Michael S. Tsirkin 2014-03-10 4992 size = skb_frag_size(frag); 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4993 if (pos + size > offset + len) 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4994 break; 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4995 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4996 i++; 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4997 pos += size; 4e1beba12d094c6 Michael S. Tsirkin 2014-03-10 4998 frag++; 9d8506cc2d7ea1f Herbert Xu 2013-11-21 4999 } 89319d3801d1d3a Herbert Xu 2008-12-15 5000 1a4cedaf65491e6 Michael S. Tsirkin 2014-03-10 5001 list_skb = list_skb->next; 89319d3801d1d3a Herbert Xu 2008-12-15 5002 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5003 if (unlikely(pskb_trim(nskb, len))) { 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5004 kfree_skb(nskb); 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5005 goto err; 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5006 } 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5007 ec47ea824774046 Alexander Duyck 2012-05-04 5008 hsize = skb_end_offset(nskb); 89319d3801d1d3a Herbert Xu 2008-12-15 5009 if (skb_cow_head(nskb, doffset + headroom)) { 89319d3801d1d3a Herbert Xu 2008-12-15 5010 kfree_skb(nskb); 89319d3801d1d3a Herbert Xu 2008-12-15 5011 goto err; 89319d3801d1d3a Herbert Xu 2008-12-15 5012 } 89319d3801d1d3a Herbert Xu 2008-12-15 5013 ec47ea824774046 Alexander Duyck 2012-05-04 5014 nskb->truesize += skb_end_offset(nskb) - hsize; 89319d3801d1d3a Herbert Xu 2008-12-15 5015 skb_release_head_state(nskb); 89319d3801d1d3a Herbert Xu 2008-12-15 5016 __skb_push(nskb, doffset); 89319d3801d1d3a Herbert Xu 2008-12-15 5017 } else { 00b229f762b020e Paolo Abeni 2021-01-19 5018 if (hsize < 0) 00b229f762b020e Paolo Abeni 2021-01-19 5019 hsize = 0; dbd50f238decfe5 Xin Long 2021-01-15 5020 if (hsize > len || !sg) dbd50f238decfe5 Xin Long 2021-01-15 5021 hsize = len; dbd50f238decfe5 Xin Long 2021-01-15 5022 c93bdd0e03e8485 Mel Gorman 2012-07-31 5023 nskb = __alloc_skb(hsize + doffset + headroom, df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 5024 GFP_ATOMIC, skb_alloc_rx_flag(head_skb), c93bdd0e03e8485 Mel Gorman 2012-07-31 5025 NUMA_NO_NODE); 89319d3801d1d3a Herbert Xu 2008-12-15 5026 89319d3801d1d3a Herbert Xu 2008-12-15 5027 if (unlikely(!nskb)) 89319d3801d1d3a Herbert Xu 2008-12-15 5028 goto err; 89319d3801d1d3a Herbert Xu 2008-12-15 5029 89319d3801d1d3a Herbert Xu 2008-12-15 5030 skb_reserve(nskb, headroom); 89319d3801d1d3a Herbert Xu 2008-12-15 5031 __skb_put(nskb, doffset); 89319d3801d1d3a Herbert Xu 2008-12-15 5032 } 89319d3801d1d3a Herbert Xu 2008-12-15 5033 f4c50d990dcf11a Herbert Xu 2006-06-22 5034 if (segs) f4c50d990dcf11a Herbert Xu 2006-06-22 5035 tail->next = nskb; f4c50d990dcf11a Herbert Xu 2006-06-22 5036 else f4c50d990dcf11a Herbert Xu 2006-06-22 5037 segs = nskb; f4c50d990dcf11a Herbert Xu 2006-06-22 5038 tail = nskb; f4c50d990dcf11a Herbert Xu 2006-06-22 5039 df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 5040 __copy_skb_header(nskb, head_skb); f4c50d990dcf11a Herbert Xu 2006-06-22 5041 b0cf97975a1cf81 Zihan Xi 2026-07-29 5042 err = skb_headers_offset_update_careful(nskb, skb_headroom(nskb) - headroom); b0cf97975a1cf81 Zihan Xi 2026-07-29 5043 if (unlikely(err)) b0cf97975a1cf81 Zihan Xi 2026-07-29 5044 goto err; fcdfe3a7fa4cb74 Vlad Yasevich 2014-07-31 5045 skb_reset_mac_len(nskb); 68c331631143f5f Pravin B Shelar 2013-02-14 5046 df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 5047 skb_copy_from_linear_data_offset(head_skb, -tnl_hlen, 68c331631143f5f Pravin B Shelar 2013-02-14 5048 nskb->data - tnl_hlen, 68c331631143f5f Pravin B Shelar 2013-02-14 5049 doffset + tnl_hlen); 89319d3801d1d3a Herbert Xu 2008-12-15 5050 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5051 if (nskb->len == len + doffset) 1cdbcb7957cf9e5 Simon Horman 2013-05-19 5052 goto perform_csum_check; 89319d3801d1d3a Herbert Xu 2008-12-15 5053 7fbeffed77c130e Alexander Duyck 2016-02-05 5054 if (!sg) { 1454c9fa9106584 Yadu Kishore 2020-03-17 5055 if (!csum) { 7fbeffed77c130e Alexander Duyck 2016-02-05 5056 if (!nskb->remcsum_offload) 6f85a124d819e1c Herbert Xu 2008-08-15 5057 nskb->ip_summed = CHECKSUM_NONE; 764434562270971 Alexander Duyck 2016-02-05 5058 SKB_GSO_CB(nskb)->csum = 764434562270971 Alexander Duyck 2016-02-05 5059 skb_copy_and_csum_bits(head_skb, offset, 1454c9fa9106584 Yadu Kishore 2020-03-17 5060 skb_put(nskb, 1454c9fa9106584 Yadu Kishore 2020-03-17 5061 len), 8d5930dfb7edbf1 Al Viro 2020-07-10 5062 len); 7e2b10c1e52ca37 Tom Herbert 2014-06-04 5063 SKB_GSO_CB(nskb)->csum_start = de843723f9b9891 Tom Herbert 2014-06-25 5064 skb_headroom(nskb) + doffset; 1454c9fa9106584 Yadu Kishore 2020-03-17 5065 } else { c624c58e08b1510 lily 2022-08-22 5066 if (skb_copy_bits(head_skb, offset, skb_put(nskb, len), len)) c624c58e08b1510 lily 2022-08-22 5067 goto err; 1454c9fa9106584 Yadu Kishore 2020-03-17 5068 } f4c50d990dcf11a Herbert Xu 2006-06-22 5069 continue; f4c50d990dcf11a Herbert Xu 2006-06-22 5070 } f4c50d990dcf11a Herbert Xu 2006-06-22 5071 8cb19905e9287a9 Michael S. Tsirkin 2014-03-10 5072 nskb_frag = skb_shinfo(nskb)->frags; f4c50d990dcf11a Herbert Xu 2006-06-22 5073 df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 5074 skb_copy_from_linear_data_offset(head_skb, offset, d626f62b11e00c1 Arnaldo Carvalho de Melo 2007-03-27 5075 skb_put(nskb, hsize), hsize); f4c50d990dcf11a Herbert Xu 2006-06-22 5076 48f6a5356a33dd7 Hyunwoo Kim 2026-05-16 5077 skb_shinfo(nskb)->flags |= (skb_shinfo(head_skb)->flags | 48f6a5356a33dd7 Hyunwoo Kim 2026-05-16 5078 skb_shinfo(frag_skb)->flags) & 06b4feb37e64e54 Jonathan Lemon 2021-01-06 5079 SKBFL_SHARED_FRAG; cef401de7be8c4e Eric Dumazet 2013-01-25 5080 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 5081 if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC)) bf5c25d608613ea Willem de Bruijn 2017-12-22 5082 goto err; bf5c25d608613ea Willem de Bruijn 2017-12-22 5083 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5084 while (pos < offset + len) { 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5085 if (i >= nfrags) { 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 5086 if (skb_orphan_frags(list_skb, GFP_ATOMIC) || 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 5087 skb_zerocopy_clone(nskb, list_skb, 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 5088 GFP_ATOMIC)) 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 5089 goto err; 2ea35288c83b3d5 Mohamed Khalfella 2023-08-31 5090 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5091 i = 0; 1a4cedaf65491e6 Michael S. Tsirkin 2014-03-10 5092 nfrags = skb_shinfo(list_skb)->nr_frags; 1a4cedaf65491e6 Michael S. Tsirkin 2014-03-10 5093 frag = skb_shinfo(list_skb)->frags; 1fd819ecb90cc9b Michael S. Tsirkin 2014-03-10 5094 frag_skb = list_skb; 48f6a5356a33dd7 Hyunwoo Kim 2026-05-16 5095 48f6a5356a33dd7 Hyunwoo Kim 2026-05-16 5096 skb_shinfo(nskb)->flags |= skb_shinfo(frag_skb)->flags & SKBFL_SHARED_FRAG; 48f6a5356a33dd7 Hyunwoo Kim 2026-05-16 5097 13acc94eff122b2 Yonghong Song 2018-03-21 5098 if (!skb_headlen(list_skb)) { 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5099 BUG_ON(!nfrags); 13acc94eff122b2 Yonghong Song 2018-03-21 5100 } else { 13acc94eff122b2 Yonghong Song 2018-03-21 5101 BUG_ON(!list_skb->head_frag); 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5102 13acc94eff122b2 Yonghong Song 2018-03-21 5103 /* to make room for head_frag. */ 13acc94eff122b2 Yonghong Song 2018-03-21 5104 i--; 13acc94eff122b2 Yonghong Song 2018-03-21 5105 frag--; 13acc94eff122b2 Yonghong Song 2018-03-21 5106 } bf5c25d608613ea Willem de Bruijn 2017-12-22 5107 1a4cedaf65491e6 Michael S. Tsirkin 2014-03-10 5108 list_skb = list_skb->next; 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5109 } 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5110 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5111 if (unlikely(skb_shinfo(nskb)->nr_frags >= 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5112 MAX_SKB_FRAGS)) { 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5113 net_warn_ratelimited( 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5114 "skb_segment: too many frags: %u %u\n", 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5115 pos, mss); ff907a11a0d68a7 Eric Dumazet 2018-07-19 5116 err = -EINVAL; 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5117 goto err; 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5118 } 9d8506cc2d7ea1f Herbert Xu 2013-11-21 5119 13acc94eff122b2 Yonghong Song 2018-03-21 5120 *nskb_frag = (i < 0) ? skb_head_frag_to_page_desc(frag_skb) : *frag; 173e7622ccb3f46 Mina Almasry 2024-05-02 5121 __skb_frag_ref(nskb_frag); 8cb19905e9287a9 Michael S. Tsirkin 2014-03-10 5122 size = skb_frag_size(nskb_frag); f4c50d990dcf11a Herbert Xu 2006-06-22 5123 f4c50d990dcf11a Herbert Xu 2006-06-22 5124 if (pos < offset) { b54c9d5bd6e38ed Jonathan Lemon 2019-07-30 5125 skb_frag_off_add(nskb_frag, offset - pos); 8cb19905e9287a9 Michael S. Tsirkin 2014-03-10 5126 skb_frag_size_sub(nskb_frag, offset - pos); f4c50d990dcf11a Herbert Xu 2006-06-22 5127 } f4c50d990dcf11a Herbert Xu 2006-06-22 5128 89319d3801d1d3a Herbert Xu 2008-12-15 5129 skb_shinfo(nskb)->nr_frags++; f4c50d990dcf11a Herbert Xu 2006-06-22 5130 f4c50d990dcf11a Herbert Xu 2006-06-22 5131 if (pos + size <= offset + len) { f4c50d990dcf11a Herbert Xu 2006-06-22 5132 i++; 4e1beba12d094c6 Michael S. Tsirkin 2014-03-10 5133 frag++; f4c50d990dcf11a Herbert Xu 2006-06-22 5134 pos += size; f4c50d990dcf11a Herbert Xu 2006-06-22 5135 } else { 8cb19905e9287a9 Michael S. Tsirkin 2014-03-10 5136 skb_frag_size_sub(nskb_frag, pos + size - (offset + len)); 89319d3801d1d3a Herbert Xu 2008-12-15 5137 goto skip_fraglist; f4c50d990dcf11a Herbert Xu 2006-06-22 5138 } f4c50d990dcf11a Herbert Xu 2006-06-22 5139 8cb19905e9287a9 Michael S. Tsirkin 2014-03-10 5140 nskb_frag++; f4c50d990dcf11a Herbert Xu 2006-06-22 5141 } f4c50d990dcf11a Herbert Xu 2006-06-22 5142 89319d3801d1d3a Herbert Xu 2008-12-15 5143 skip_fraglist: f4c50d990dcf11a Herbert Xu 2006-06-22 5144 nskb->data_len = len - hsize; f4c50d990dcf11a Herbert Xu 2006-06-22 5145 nskb->len += nskb->data_len; f4c50d990dcf11a Herbert Xu 2006-06-22 5146 nskb->truesize += nskb->data_len; ec5f06156423889 Pravin B Shelar 2013-03-07 5147 1cdbcb7957cf9e5 Simon Horman 2013-05-19 5148 perform_csum_check: 7fbeffed77c130e Alexander Duyck 2016-02-05 5149 if (!csum) { ff907a11a0d68a7 Eric Dumazet 2018-07-19 5150 if (skb_has_shared_frag(nskb) && ff907a11a0d68a7 Eric Dumazet 2018-07-19 5151 __skb_linearize(nskb)) ddff00d420432d5 Alexander Duyck 2016-02-05 5152 goto err; ff907a11a0d68a7 Eric Dumazet 2018-07-19 5153 7fbeffed77c130e Alexander Duyck 2016-02-05 5154 if (!nskb->remcsum_offload) ec5f06156423889 Pravin B Shelar 2013-03-07 5155 nskb->ip_summed = CHECKSUM_NONE; 764434562270971 Alexander Duyck 2016-02-05 5156 SKB_GSO_CB(nskb)->csum = 764434562270971 Alexander Duyck 2016-02-05 5157 skb_checksum(nskb, doffset, 764434562270971 Alexander Duyck 2016-02-05 5158 nskb->len - doffset, 0); 7e2b10c1e52ca37 Tom Herbert 2014-06-04 5159 SKB_GSO_CB(nskb)->csum_start = 7e2b10c1e52ca37 Tom Herbert 2014-06-04 5160 skb_headroom(nskb) + doffset; ec5f06156423889 Pravin B Shelar 2013-03-07 5161 } df5771ffefb13f8 Michael S. Tsirkin 2014-03-10 5162 } while ((offset += len) < head_skb->len); f4c50d990dcf11a Herbert Xu 2006-06-22 5163 bec3cfdca36bf43 Eric Dumazet 2014-10-03 5164 /* Some callers want to get the end of the list. bec3cfdca36bf43 Eric Dumazet 2014-10-03 5165 * Put it in segs->prev to avoid walking the list. bec3cfdca36bf43 Eric Dumazet 2014-10-03 5166 * (see validate_xmit_skb_list() for example) bec3cfdca36bf43 Eric Dumazet 2014-10-03 5167 */ bec3cfdca36bf43 Eric Dumazet 2014-10-03 5168 segs->prev = tail; 432c856fcf45c46 Toshiaki Makita 2014-10-27 5169 802ab55adc39a06 Alexander Duyck 2016-04-10 5170 if (partial_segs) { 07b26c9454a2a19 Steffen Klassert 2016-09-19 5171 struct sk_buff *iter; 802ab55adc39a06 Alexander Duyck 2016-04-10 5172 int type = skb_shinfo(head_skb)->gso_type; 07b26c9454a2a19 Steffen Klassert 2016-09-19 5173 unsigned short gso_size = skb_shinfo(head_skb)->gso_size; 802ab55adc39a06 Alexander Duyck 2016-04-10 5174 802ab55adc39a06 Alexander Duyck 2016-04-10 5175 /* Update type to add partial and then remove dodgy if set */ 07b26c9454a2a19 Steffen Klassert 2016-09-19 5176 type |= (features & NETIF_F_GSO_PARTIAL) / NETIF_F_GSO_PARTIAL * SKB_GSO_PARTIAL; 802ab55adc39a06 Alexander Duyck 2016-04-10 5177 type &= ~SKB_GSO_DODGY; 802ab55adc39a06 Alexander Duyck 2016-04-10 5178 802ab55adc39a06 Alexander Duyck 2016-04-10 5179 /* Update GSO info and prepare to start updating headers on 802ab55adc39a06 Alexander Duyck 2016-04-10 5180 * our way back down the stack of protocols. 802ab55adc39a06 Alexander Duyck 2016-04-10 5181 */ 07b26c9454a2a19 Steffen Klassert 2016-09-19 5182 for (iter = segs; iter; iter = iter->next) { 07b26c9454a2a19 Steffen Klassert 2016-09-19 5183 skb_shinfo(iter)->gso_size = gso_size; 07b26c9454a2a19 Steffen Klassert 2016-09-19 5184 skb_shinfo(iter)->gso_segs = partial_segs; 07b26c9454a2a19 Steffen Klassert 2016-09-19 5185 skb_shinfo(iter)->gso_type = type; 07b26c9454a2a19 Steffen Klassert 2016-09-19 5186 SKB_GSO_CB(iter)->data_offset = skb_headroom(iter) + doffset; 07b26c9454a2a19 Steffen Klassert 2016-09-19 5187 } 07b26c9454a2a19 Steffen Klassert 2016-09-19 5188 07b26c9454a2a19 Steffen Klassert 2016-09-19 5189 if (tail->len - doffset <= gso_size) 07b26c9454a2a19 Steffen Klassert 2016-09-19 5190 skb_shinfo(tail)->gso_size = 0; 07b26c9454a2a19 Steffen Klassert 2016-09-19 5191 else if (tail != segs) 07b26c9454a2a19 Steffen Klassert 2016-09-19 5192 skb_shinfo(tail)->gso_segs = DIV_ROUND_UP(tail->len - doffset, gso_size); 802ab55adc39a06 Alexander Duyck 2016-04-10 5193 } 802ab55adc39a06 Alexander Duyck 2016-04-10 5194 432c856fcf45c46 Toshiaki Makita 2014-10-27 5195 /* Following permits correct backpressure, for protocols 432c856fcf45c46 Toshiaki Makita 2014-10-27 5196 * using skb_set_owner_w(). 432c856fcf45c46 Toshiaki Makita 2014-10-27 5197 * Idea is to tranfert ownership from head_skb to last segment. 432c856fcf45c46 Toshiaki Makita 2014-10-27 5198 */ 432c856fcf45c46 Toshiaki Makita 2014-10-27 5199 if (head_skb->destructor == sock_wfree) { 432c856fcf45c46 Toshiaki Makita 2014-10-27 5200 swap(tail->truesize, head_skb->truesize); 432c856fcf45c46 Toshiaki Makita 2014-10-27 5201 swap(tail->destructor, head_skb->destructor); 432c856fcf45c46 Toshiaki Makita 2014-10-27 5202 swap(tail->sk, head_skb->sk); 432c856fcf45c46 Toshiaki Makita 2014-10-27 5203 } f4c50d990dcf11a Herbert Xu 2006-06-22 5204 return segs; f4c50d990dcf11a Herbert Xu 2006-06-22 5205 f4c50d990dcf11a Herbert Xu 2006-06-22 5206 err: 289dccbe141e01e Eric Dumazet 2013-12-20 5207 kfree_skb_list(segs); f4c50d990dcf11a Herbert Xu 2006-06-22 @5208 return ERR_PTR(err); f4c50d990dcf11a Herbert Xu 2006-06-22 5209 } f4c50d990dcf11a Herbert Xu 2006-06-22 5210 EXPORT_SYMBOL_GPL(skb_segment); f4c50d990dcf11a Herbert Xu 2006-06-22 5211 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki