* [PATCH v2 2/2] test_bpf: Introduce an skb_segment test for frag_list whose head_frag=true and gso_size was mangled @ 2024-06-26 6:55 Fred Li 2024-06-26 6:55 ` [PATCH v2 1/2] net: Fix skb_segment when splitting gso_size mangled skb having linear-headed frag_list whose head_frag=true Fred Li 2024-06-26 6:55 ` [PATCH v2 0/2] net: Fix BUG_ON for segment frag_list with mangled gso_size and head_frag is true Fred Li 0 siblings, 2 replies; 23+ messages in thread From: Fred Li @ 2024-06-26 6:55 UTC (permalink / raw) To: davem, edumazet, kuba, pabeni, aleksander.lobakin, sashal, linux, hawk, nbd, mkhalfella, ast, daniel, andrii, martin.lau, song, yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa Cc: netdev, linux-kernel, bpf, Fred Li This is a reproducer test that mimics the input skbs that lead to the mentioned BUG_ON and validates the fix submitted in patch 1. Signed-off-by: Fred Li <dracodingfly@gmail.com> --- lib/test_bpf.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/lib/test_bpf.c b/lib/test_bpf.c index ecde4216201e..a38d2d09ca01 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -14706,6 +14706,63 @@ static __init struct sk_buff *build_test_skb_linear_no_head_frag(void) return NULL; } +static __init struct sk_buff *build_test_skb_head_frag(void) +{ + u32 headroom = 192, doffset = 66, alloc_size = 1536; + struct sk_buff *skb[2]; + struct page *page[17]; + int i, data_size = 125; + int j; + + skb[0] = dev_alloc_skb(headroom + alloc_size); + if (!skb[0]) + return NULL; + + skb_reserve(skb[0], headroom + doffset); + skb_put(skb[0], data_size); + skb[0]->mac_header = 192; + + skb[0]->protocol = htons(ETH_P_IP); + skb[0]->network_header = 206; + + for (i = 0; i < 17; i++) { + page[i] = alloc_page(GFP_KERNEL); + if (!page[i]) + goto err_page; + + skb_add_rx_frag(skb[0], i, page[i], 0, data_size, data_size); + } + + skb[1] = dev_alloc_skb(headroom + alloc_size); + if (!skb[1]) + goto err_page; + + skb_reserve(skb[1], headroom + doffset); + skb_put(skb[1], data_size); + + /* setup shinfo */ + skb_shinfo(skb[0])->gso_size = 75; + skb_shinfo(skb[0])->gso_type = SKB_GSO_TCPV4; + skb_shinfo(skb[0])->gso_type |= SKB_GSO_UDP_TUNNEL|SKB_GSO_TCP_FIXEDID|SKB_GSO_DODGY; + skb_shinfo(skb[0])->gso_segs = 0; + skb_shinfo(skb[0])->frag_list = skb[1]; + skb_shinfo(skb[0])->hwtstamps.hwtstamp = 1000; + + /* adjust skb[0]'s len */ + skb[0]->len += skb[1]->len; + skb[0]->data_len += skb[1]->len; + skb[0]->truesize += skb[1]->truesize; + + return skb[0]; + +err_page: + kfree_skb(skb[0]); + for (j = 0; j < i; j++) + __free_page(page[j]); + + return NULL; +} + struct skb_segment_test { const char *descr; struct sk_buff *(*build_skb)(void); @@ -14727,6 +14784,13 @@ static struct skb_segment_test skb_segment_tests[] __initconst = { NETIF_F_LLTX | NETIF_F_GRO | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_STAG_TX + }, + { + .descr = "gso_with_head_frag", + .build_skb = build_test_skb_head_frag, + .features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SHIFT | + NETIF_F_TSO_ECN | NETIF_F_TSO_MANGLEID | NETIF_F_TSO6 | + NETIF_F_GSO_SCTP | NETIF_F_GSO_UDP_L4 | NETIF_F_GSO_FRAGLIST } }; -- 2.33.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 1/2] net: Fix skb_segment when splitting gso_size mangled skb having linear-headed frag_list whose head_frag=true 2024-06-26 6:55 [PATCH v2 2/2] test_bpf: Introduce an skb_segment test for frag_list whose head_frag=true and gso_size was mangled Fred Li @ 2024-06-26 6:55 ` Fred Li 2024-07-02 9:23 ` Paolo Abeni 2024-06-26 6:55 ` [PATCH v2 0/2] net: Fix BUG_ON for segment frag_list with mangled gso_size and head_frag is true Fred Li 1 sibling, 1 reply; 23+ messages in thread From: Fred Li @ 2024-06-26 6:55 UTC (permalink / raw) To: davem, edumazet, kuba, pabeni, aleksander.lobakin, sashal, linux, hawk, nbd, mkhalfella, ast, daniel, andrii, martin.lau, song, yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa Cc: netdev, linux-kernel, bpf, Fred Li When using calico bpf based NAT, hits a kernel BUG_ON at function skb_segment(), line 4560. Performing NAT translation when accessing a Service IP across subnets, the calico will encap vxlan and calls the bpf_skb_adjust_room to decrease the gso_size, and then call bpf_redirect send packets out. 4438 struct sk_buff *skb_segment(struct sk_buff *head_skb, 4439 netdev_features_t features) 4440 { 4441 struct sk_buff *segs = NULL; 4442 struct sk_buff *tail = NULL; ... 4558 if (hsize <= 0 && i >= nfrags && skb_headlen(list_skb) && 4559 (skb_headlen(list_skb) == len || sg)) { 4560 BUG_ON(skb_headlen(list_skb) > len); 4561 4562 nskb = skb_clone(list_skb, GFP_ATOMIC); 4563 if (unlikely(!nskb)) 4564 goto err; call stack: ... [exception RIP: skb_segment+3016] RIP: ffffffffb97df2a8 RSP: ffffa3f2cce08728 RFLAGS: 00010293 RAX: 000000000000007d RBX: 00000000fffff7b3 RCX: 0000000000000011 RDX: 0000000000000000 RSI: ffff895ea32c76c0 RDI: 00000000000008c1 RBP: ffffa3f2cce087f8 R8: 000000000000088f R9: 0000000000000011 R10: 000000000000090c R11: ffff895e47e68000 R12: ffff895eb2022f00 R13: 000000000000004b R14: ffff895ecdaf2000 R15: ffff895eb2023f00 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 #9 [ffffa3f2cce08720] skb_segment at ffffffffb97ded63 ... The skb has the following properties: doffset = 66 list_skb = skb_shinfo(skb)->frag_list list_skb->head_frag = true skb->len = 2441 && skb->data_len = 2250 skb_shinfo(skb)->nr_frags = 17 skb_shinfo(skb)->gso_size = 75 skb_shinfo(skb)->frags[0...16].bv_len = 125 list_skb->len = 125 list_skb->data_len = 0 When slicing the frag_list skb, there three cases: 1. Only *non* head_frag sg will be false, only when skb_headlen(list_skb)==len is satisfied, it will enter the branch at line 4560, and there will be no crash. 2. Mixed head_frag sg will be false, Only when skb_headlen(list_skb)==len is satisfied, it will enter the branch at line 4560, and there will be no crash. 3. Only frag_list with head_frag=true sg is true, three cases below: (1) skb_headlen(list_skb)==len is satisfied, it will enter the branch at line 4560, and there will be no crash. (2) skb_headlen(list_skb)<len is satisfied, it will enter the branch at line 4560, and there will be no crash. (3) skb_headlen(list_skb)>len is satisfied, it will be crash. Applying this patch, three cases will be: 1. Only *non* head_frag sg will be false. No difference with before. 2. Mixed head_frag sg will be false. No difference with before. 3. Only frag_list with head_frag=true sg is true, there also three cases: (1) skb_headlen(list_skb)==len is satisfied, no difference with before. (2) skb_headlen(list_skb)<len is satisfied, will be revert to copying in this case. (3) skb_headlen(list_skb)>len is satisfied, will be revert to copying in this case. Since commit 13acc94eff122("net: permit skb_segment on head_frag frag_list skb"), it is allowed to segment the head_frag frag_list skb. Signed-off-by: Fred Li <dracodingfly@gmail.com> --- net/core/skbuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index f0a9ef1aeaa2..b1dab1b071fc 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4556,7 +4556,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, hsize = skb_headlen(head_skb) - offset; if (hsize <= 0 && i >= nfrags && skb_headlen(list_skb) && - (skb_headlen(list_skb) == len || sg)) { + (skb_headlen(list_skb) == len)) { BUG_ON(skb_headlen(list_skb) > len); nskb = skb_clone(list_skb, GFP_ATOMIC); -- 2.33.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/2] net: Fix skb_segment when splitting gso_size mangled skb having linear-headed frag_list whose head_frag=true 2024-06-26 6:55 ` [PATCH v2 1/2] net: Fix skb_segment when splitting gso_size mangled skb having linear-headed frag_list whose head_frag=true Fred Li @ 2024-07-02 9:23 ` Paolo Abeni 2024-07-03 12:21 ` Fred Li 0 siblings, 1 reply; 23+ messages in thread From: Paolo Abeni @ 2024-07-02 9:23 UTC (permalink / raw) To: Fred Li, davem, edumazet, kuba, aleksander.lobakin, sashal, linux, hawk, nbd, mkhalfella, ast, daniel, andrii, martin.lau, song, yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa Cc: netdev, linux-kernel, bpf On Wed, 2024-06-26 at 14:55 +0800, Fred Li wrote: > When using calico bpf based NAT, hits a kernel BUG_ON at function > skb_segment(), line 4560. Performing NAT translation when accessing > a Service IP across subnets, the calico will encap vxlan and calls the > bpf_skb_adjust_room to decrease the gso_size, and then call bpf_redirect > send packets out. > > 4438 struct sk_buff *skb_segment(struct sk_buff *head_skb, > 4439 netdev_features_t features) > 4440 { > 4441 struct sk_buff *segs = NULL; > 4442 struct sk_buff *tail = NULL; > ... > 4558 if (hsize <= 0 && i >= nfrags && skb_headlen(list_skb) && > 4559 (skb_headlen(list_skb) == len || sg)) { > 4560 BUG_ON(skb_headlen(list_skb) > len); > 4561 > 4562 nskb = skb_clone(list_skb, GFP_ATOMIC); > 4563 if (unlikely(!nskb)) > 4564 goto err; > > call stack: > ... > [exception RIP: skb_segment+3016] > RIP: ffffffffb97df2a8 RSP: ffffa3f2cce08728 RFLAGS: 00010293 > RAX: 000000000000007d RBX: 00000000fffff7b3 RCX: 0000000000000011 > RDX: 0000000000000000 RSI: ffff895ea32c76c0 RDI: 00000000000008c1 > RBP: ffffa3f2cce087f8 R8: 000000000000088f R9: 0000000000000011 > R10: 000000000000090c R11: ffff895e47e68000 R12: ffff895eb2022f00 > R13: 000000000000004b R14: ffff895ecdaf2000 R15: ffff895eb2023f00 > ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 > #9 [ffffa3f2cce08720] skb_segment at ffffffffb97ded63 > ... > > The skb has the following properties: > doffset = 66 > list_skb = skb_shinfo(skb)->frag_list > list_skb->head_frag = true > skb->len = 2441 && skb->data_len = 2250 > skb_shinfo(skb)->nr_frags = 17 > skb_shinfo(skb)->gso_size = 75 > skb_shinfo(skb)->frags[0...16].bv_len = 125 > list_skb->len = 125 > list_skb->data_len = 0 > > When slicing the frag_list skb, there three cases: > 1. Only *non* head_frag > sg will be false, only when skb_headlen(list_skb)==len is satisfied, > it will enter the branch at line 4560, and there will be no crash. > 2. Mixed head_frag > sg will be false, Only when skb_headlen(list_skb)==len is satisfied, > it will enter the branch at line 4560, and there will be no crash. > 3. Only frag_list with head_frag=true > sg is true, three cases below: > (1) skb_headlen(list_skb)==len is satisfied, it will enter the branch > at line 4560, and there will be no crash. > (2) skb_headlen(list_skb)<len is satisfied, it will enter the branch > at line 4560, and there will be no crash. > (3) skb_headlen(list_skb)>len is satisfied, it will be crash. > > Applying this patch, three cases will be: > 1. Only *non* head_frag > sg will be false. No difference with before. > 2. Mixed head_frag > sg will be false. No difference with before. > 3. Only frag_list with head_frag=true > sg is true, there also three cases: > (1) skb_headlen(list_skb)==len is satisfied, no difference with before. > (2) skb_headlen(list_skb)<len is satisfied, will be revert to copying > in this case. > (3) skb_headlen(list_skb)>len is satisfied, will be revert to copying > in this case. > > Since commit 13acc94eff122("net: permit skb_segment on head_frag frag_list > skb"), it is allowed to segment the head_frag frag_list skb. > > Signed-off-by: Fred Li <dracodingfly@gmail.com> > --- > net/core/skbuff.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/net/core/skbuff.c b/net/core/skbuff.c > index f0a9ef1aeaa2..b1dab1b071fc 100644 > --- a/net/core/skbuff.c > +++ b/net/core/skbuff.c > @@ -4556,7 +4556,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, > hsize = skb_headlen(head_skb) - offset; > > if (hsize <= 0 && i >= nfrags && skb_headlen(list_skb) && > - (skb_headlen(list_skb) == len || sg)) { > + (skb_headlen(list_skb) == len)) { > BUG_ON(skb_headlen(list_skb) > len); > > nskb = skb_clone(list_skb, GFP_ATOMIC); I must admit I more than a bit lost in the many turns of skb_segment(), but the above does not look like the correct solution, as it will make the later BUG_ON() unreachable/meaningless. Do I read correctly that when the BUG_ON() triggers: list_skb->len is 125 len is 75 list_skb->frag_head is true It looks like skb_segment() is becoming even and ever more complex to cope with unexpected skb layouts, only possibly when skb_segment() is called by some BPF helpers. I think it should be up to the helper itself to adjust the skb and/or the device features to respect skb_segment() constraints, instead of making the common code increasingly not maintainable. Thanks, Paolo ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/2] net: Fix skb_segment when splitting gso_size mangled skb having linear-headed frag_list whose head_frag=true 2024-07-02 9:23 ` Paolo Abeni @ 2024-07-03 12:21 ` Fred Li 2024-07-06 14:26 ` Willem de Bruijn 0 siblings, 1 reply; 23+ messages in thread From: Fred Li @ 2024-07-03 12:21 UTC (permalink / raw) To: pabeni Cc: aleksander.lobakin, andrii, ast, bpf, daniel, davem, dracodingfly, edumazet, haoluo, hawk, john.fastabend, jolsa, kpsingh, kuba, linux-kernel, linux, martin.lau, mkhalfella, nbd, netdev, sashal, sdf, song, yonghong.song, herbert > I must admit I more than a bit lost in the many turns of skb_segment(), > but the above does not look like the correct solution, as it will make > the later BUG_ON() unreachable/meaningless. Sorry, the subsequent BUG_ON maybe should be removed in this patch, because for skb_headlen(list_skb) > len, it will continue splitting as commit 13acc94eff122 (net: permit skb_segment on head_frag frag_list skb) does. > > Do I read correctly that when the BUG_ON() triggers: > > list_skb->len is 125 > len is 75 > list_skb->frag_head is true > yes, it's correct. list_skb->len is 125 gso_size is 75, also the len in the BUG_ON conditon list_skb->head_frag is true > It looks like skb_segment() is becoming even and ever more complex to > cope with unexpected skb layouts, only possibly when skb_segment() is > called by some BPF helpers. > > Thanks, > > Paolo I'll wait for more suggestions from others. Thanks Fred Li ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/2] net: Fix skb_segment when splitting gso_size mangled skb having linear-headed frag_list whose head_frag=true 2024-07-03 12:21 ` Fred Li @ 2024-07-06 14:26 ` Willem de Bruijn 2024-07-08 14:31 ` [PATCH] net: linearizing skb when downgrade gso_size Fred Li ` (3 more replies) 0 siblings, 4 replies; 23+ messages in thread From: Willem de Bruijn @ 2024-07-06 14:26 UTC (permalink / raw) To: Fred Li, pabeni Cc: aleksander.lobakin, andrii, ast, bpf, daniel, davem, dracodingfly, edumazet, haoluo, hawk, john.fastabend, jolsa, kpsingh, kuba, linux-kernel, linux, martin.lau, mkhalfella, nbd, netdev, sashal, sdf, song, yonghong.song, herbert Fred Li wrote: > > I must admit I more than a bit lost in the many turns of skb_segment(), > > but the above does not look like the correct solution, as it will make > > the later BUG_ON() unreachable/meaningless. > > Sorry, the subsequent BUG_ON maybe should be removed in this patch, because > for skb_headlen(list_skb) > len, it will continue splitting as commit 13acc94eff122 > (net: permit skb_segment on head_frag frag_list skb) does. > > > > > Do I read correctly that when the BUG_ON() triggers: > > > > list_skb->len is 125 > > len is 75 > > list_skb->frag_head is true > > > > yes, it's correct. > list_skb->len is 125 > gso_size is 75, also the len in the BUG_ON conditon > list_skb->head_frag is true > > > It looks like skb_segment() is becoming even and ever more complex to > > cope with unexpected skb layouts, only possibly when skb_segment() is > > called by some BPF helpers. > > > > Thanks, > > > > Paolo > > I'll wait for more suggestions from others. In general, agreed with Paolo. Segmentation is getting ever more complex and the code hard to follow. Maybe at some point we'll have to bite the bullet and seriously refactor it. Or at least parts, such as the frag_list handling case. But that kills any odds of backporting fixes, so not if we can avoid it. In particular, changing gso_size on skbs with frag_list is fragile. Instead of adding another special case, how about just linearizing sbks after BPF calls adjust_room (at least if called without BPF_F_ADJ_ROOM_FIXED_GSO) if they have frag_list. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH] net: linearizing skb when downgrade gso_size 2024-07-06 14:26 ` Willem de Bruijn @ 2024-07-08 14:31 ` Fred Li 2024-07-09 15:53 ` Willem de Bruijn 2024-07-17 5:35 ` [PATCH v3] " Fred Li ` (2 subsequent siblings) 3 siblings, 1 reply; 23+ messages in thread From: Fred Li @ 2024-07-08 14:31 UTC (permalink / raw) To: willemdebruijn.kernel Cc: aleksander.lobakin, andrii, ast, bpf, daniel, davem, dracodingfly, edumazet, haoluo, hawk, herbert, john.fastabend, jolsa, kpsingh, kuba, linux-kernel, linux, martin.lau, mkhalfella, nbd, netdev, pabeni, sashal, sdf, song, yonghong.song Here is a patch that linearizing skb when downgrade gso_size and sg should disabled, If there are no issues, I will submit a formal patch shortly. Signed-off-by: Fred Li <dracodingfly@gmail.com> --- include/linux/skbuff.h | 22 ++++++++++++++++++++++ net/core/filter.c | 16 ++++++++++++---- net/core/skbuff.c | 19 ++----------------- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 5f11f9873341..99b7fc1e826a 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2400,6 +2400,28 @@ static inline unsigned int skb_headlen(const struct sk_buff *skb) return skb->len - skb->data_len; } +static inline bool skb_is_nonsg(const struct sk_buff *skb) +{ + struct sk_buff *list_skb = skb_shinfo(skb)->frag_list; + struct sk_buff *check_skb; + for (check_skb = list_skb; check_skb; check_skb = check_skb->next) { + if (skb_headlen(check_skb) && !check_skb->head_frag) { + /* gso_size is untrusted, and we have a frag_list with + * a linear non head_frag item. + * + * If head_skb's headlen does not fit requested gso_size, + * it means that the frag_list members do NOT terminate + * on exact gso_size boundaries. Hence we cannot perform + * skb_frag_t page sharing. Therefore we must fallback to + * copying the frag_list skbs; we do so by disabling SG. + */ + return true; + } + } + + return false; +} + static inline unsigned int __skb_pagelen(const struct sk_buff *skb) { unsigned int i, len = 0; diff --git a/net/core/filter.c b/net/core/filter.c index df4578219e82..c0e6e7f28635 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3525,13 +3525,21 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, if (skb_is_gso(skb)) { struct skb_shared_info *shinfo = skb_shinfo(skb); - /* Due to header grow, MSS needs to be downgraded. */ - if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) - skb_decrease_gso_size(shinfo, len_diff); - /* Header must be checked, and gso_segs recomputed. */ shinfo->gso_type |= gso_type; shinfo->gso_segs = 0; + + /* Due to header grow, MSS needs to be downgraded. + * There is BUG_ON When segment the frag_list with + * head_frag true so linearize skb after downgrade + * the MSS. + */ + if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) { + skb_decrease_gso_size(shinfo, len_diff); + if (skb_is_nonsg(skb)) + return skb_linearize(skb) ? : 0; + } + } return 0; diff --git a/net/core/skbuff.c b/net/core/skbuff.c index b1dab1b071fc..81e018185527 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4458,23 +4458,8 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) && mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) { - struct sk_buff *check_skb; - - for (check_skb = list_skb; check_skb; check_skb = check_skb->next) { - if (skb_headlen(check_skb) && !check_skb->head_frag) { - /* gso_size is untrusted, and we have a frag_list with - * a linear non head_frag item. - * - * If head_skb's headlen does not fit requested gso_size, - * it means that the frag_list members do NOT terminate - * on exact gso_size boundaries. Hence we cannot perform - * skb_frag_t page sharing. Therefore we must fallback to - * copying the frag_list skbs; we do so by disabling SG. - */ - features &= ~NETIF_F_SG; - break; - } - } + if (skb_is_nonsg(head_skb)) + features &= ~NETIF_F_SG; } __skb_push(head_skb, doffset); -- 2.33.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH] net: linearizing skb when downgrade gso_size 2024-07-08 14:31 ` [PATCH] net: linearizing skb when downgrade gso_size Fred Li @ 2024-07-09 15:53 ` Willem de Bruijn 2024-07-09 20:16 ` Herbert Xu 2024-07-12 8:17 ` Fred Li 0 siblings, 2 replies; 23+ messages in thread From: Willem de Bruijn @ 2024-07-09 15:53 UTC (permalink / raw) To: Fred Li, willemdebruijn.kernel Cc: aleksander.lobakin, andrii, ast, bpf, daniel, davem, dracodingfly, edumazet, haoluo, hawk, herbert, john.fastabend, jolsa, kpsingh, kuba, linux-kernel, linux, martin.lau, mkhalfella, nbd, netdev, pabeni, sashal, sdf, song, yonghong.song Fred Li wrote: > Here is a patch that linearizing skb when downgrade > gso_size and sg should disabled, If there are no issues, > I will submit a formal patch shortly. Target bpf. Probably does not need quite as many direct CCs. > Signed-off-by: Fred Li <dracodingfly@gmail.com> > --- > include/linux/skbuff.h | 22 ++++++++++++++++++++++ > net/core/filter.c | 16 ++++++++++++---- > net/core/skbuff.c | 19 ++----------------- > 3 files changed, 36 insertions(+), 21 deletions(-) > > diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h > index 5f11f9873341..99b7fc1e826a 100644 > --- a/include/linux/skbuff.h > +++ b/include/linux/skbuff.h > @@ -2400,6 +2400,28 @@ static inline unsigned int skb_headlen(const struct sk_buff *skb) > return skb->len - skb->data_len; > } > > +static inline bool skb_is_nonsg(const struct sk_buff *skb) > +{ is_nonsg does not cover the functionality, which is fairly subtle. But maybe we don't need this function at all, see below.. > + struct sk_buff *list_skb = skb_shinfo(skb)->frag_list; > + struct sk_buff *check_skb; No need for separate check_skb > + for (check_skb = list_skb; check_skb; check_skb = check_skb->next) { > + if (skb_headlen(check_skb) && !check_skb->head_frag) { > + /* gso_size is untrusted, and we have a frag_list with > + * a linear non head_frag item. > + * > + * If head_skb's headlen does not fit requested gso_size, > + * it means that the frag_list members do NOT terminate > + * on exact gso_size boundaries. Hence we cannot perform > + * skb_frag_t page sharing. Therefore we must fallback to > + * copying the frag_list skbs; we do so by disabling SG. > + */ > + return true; > + } > + } > + > + return false; > +} > + > static inline unsigned int __skb_pagelen(const struct sk_buff *skb) > { > unsigned int i, len = 0; > diff --git a/net/core/filter.c b/net/core/filter.c > index df4578219e82..c0e6e7f28635 100644 > --- a/net/core/filter.c > +++ b/net/core/filter.c > @@ -3525,13 +3525,21 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, > if (skb_is_gso(skb)) { > struct skb_shared_info *shinfo = skb_shinfo(skb); > > - /* Due to header grow, MSS needs to be downgraded. */ > - if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) > - skb_decrease_gso_size(shinfo, len_diff); > - > /* Header must be checked, and gso_segs recomputed. */ > shinfo->gso_type |= gso_type; > shinfo->gso_segs = 0; > + > + /* Due to header grow, MSS needs to be downgraded. > + * There is BUG_ON When segment the frag_list with > + * head_frag true so linearize skb after downgrade > + * the MSS. > + */ > + if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) { > + skb_decrease_gso_size(shinfo, len_diff); > + if (skb_is_nonsg(skb)) > + return skb_linearize(skb) ? : 0; > + } > + No need for ternary statement. Instead of the complex test in skb_is_nonsg, can we just assume that alignment will be off if having frag_list and changing gso_size. The same will apply to bpf_skb_net_shrink too. Not sure that it is okay to linearize inside a BPF helper function. Hopefully bpf experts can chime in on that. > } > > return 0; > diff --git a/net/core/skbuff.c b/net/core/skbuff.c > index b1dab1b071fc..81e018185527 100644 > --- a/net/core/skbuff.c > +++ b/net/core/skbuff.c > @@ -4458,23 +4458,8 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, > > if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) && > mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) { > - struct sk_buff *check_skb; > - > - for (check_skb = list_skb; check_skb; check_skb = check_skb->next) { > - if (skb_headlen(check_skb) && !check_skb->head_frag) { > - /* gso_size is untrusted, and we have a frag_list with > - * a linear non head_frag item. > - * > - * If head_skb's headlen does not fit requested gso_size, > - * it means that the frag_list members do NOT terminate > - * on exact gso_size boundaries. Hence we cannot perform > - * skb_frag_t page sharing. Therefore we must fallback to > - * copying the frag_list skbs; we do so by disabling SG. > - */ > - features &= ~NETIF_F_SG; > - break; > - } > - } > + if (skb_is_nonsg(head_skb)) > + features &= ~NETIF_F_SG; > } > > __skb_push(head_skb, doffset); > -- > 2.33.0 > ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] net: linearizing skb when downgrade gso_size 2024-07-09 15:53 ` Willem de Bruijn @ 2024-07-09 20:16 ` Herbert Xu 2024-07-09 21:29 ` Willem de Bruijn 2024-07-12 8:17 ` Fred Li 1 sibling, 1 reply; 23+ messages in thread From: Herbert Xu @ 2024-07-09 20:16 UTC (permalink / raw) To: Willem de Bruijn Cc: Fred Li, aleksander.lobakin, andrii, ast, bpf, daniel, davem, edumazet, haoluo, hawk, john.fastabend, jolsa, kpsingh, kuba, linux-kernel, linux, martin.lau, mkhalfella, nbd, netdev, pabeni, sashal, sdf, song, yonghong.song On Tue, Jul 09, 2024 at 11:53:21AM -0400, Willem de Bruijn wrote: > > > + /* Due to header grow, MSS needs to be downgraded. > > + * There is BUG_ON When segment the frag_list with > > + * head_frag true so linearize skb after downgrade > > + * the MSS. > > + */ This sounds completely wrong. You should never grow the TCP header by changing gso_size. What is the usage-scenario for this? Think about it, if a router forwards a TCP packet, and ends up growing its TCP header and then splits the packet into two, then this router is brain-dead. Cheers, -- Email: Herbert Xu <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] net: linearizing skb when downgrade gso_size 2024-07-09 20:16 ` Herbert Xu @ 2024-07-09 21:29 ` Willem de Bruijn 2024-07-10 23:06 ` Herbert Xu 0 siblings, 1 reply; 23+ messages in thread From: Willem de Bruijn @ 2024-07-09 21:29 UTC (permalink / raw) To: Herbert Xu, Willem de Bruijn Cc: Fred Li, aleksander.lobakin, andrii, ast, bpf, daniel, davem, edumazet, haoluo, hawk, john.fastabend, jolsa, kpsingh, kuba, linux-kernel, linux, martin.lau, mkhalfella, nbd, netdev, pabeni, sashal, sdf, song, yonghong.song Herbert Xu wrote: > On Tue, Jul 09, 2024 at 11:53:21AM -0400, Willem de Bruijn wrote: > > > > > + /* Due to header grow, MSS needs to be downgraded. > > > + * There is BUG_ON When segment the frag_list with > > > + * head_frag true so linearize skb after downgrade > > > + * the MSS. > > > + */ > > This sounds completely wrong. You should never grow the TCP header > by changing gso_size. What is the usage-scenario for this? > > Think about it, if a router forwards a TCP packet, and ends up > growing its TCP header and then splits the packet into two, then > this router is brain-dead. This is an unfortunate feature, but already exists. It decreases gso_size to account for tunnel headers. For USO, we added BPF_F_ADJ_ROOM_FIXED_GSO to avoid this in better, newer users. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] net: linearizing skb when downgrade gso_size 2024-07-09 21:29 ` Willem de Bruijn @ 2024-07-10 23:06 ` Herbert Xu 0 siblings, 0 replies; 23+ messages in thread From: Herbert Xu @ 2024-07-10 23:06 UTC (permalink / raw) To: Willem de Bruijn Cc: Fred Li, aleksander.lobakin, andrii, ast, bpf, daniel, davem, edumazet, haoluo, hawk, john.fastabend, jolsa, kpsingh, kuba, linux-kernel, linux, martin.lau, mkhalfella, nbd, netdev, pabeni, sashal, sdf, song, yonghong.song On Tue, Jul 09, 2024 at 05:29:59PM -0400, Willem de Bruijn wrote: > > This is an unfortunate feature, but already exists. > > It decreases gso_size to account for tunnel headers. Growing the tunnel header is totally fine. But you should not decrease gso_size because of that. Instead the correct course of action is to drop the packet and generate an ICMP if it no longer fits the MTU. A router that resegments a TCP packet at the TCP-level (not IP) is brain-dead. Cheers, -- Email: Herbert Xu <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] net: linearizing skb when downgrade gso_size 2024-07-09 15:53 ` Willem de Bruijn 2024-07-09 20:16 ` Herbert Xu @ 2024-07-12 8:17 ` Fred Li 1 sibling, 0 replies; 23+ messages in thread From: Fred Li @ 2024-07-12 8:17 UTC (permalink / raw) To: willemdebruijn.kernel; +Cc: bpf, herbert, linux-kernel, netdev > No need for ternary statement. > > Instead of the complex test in skb_is_nonsg, can we just assume that > alignment will be off if having frag_list and changing gso_size. > > The same will apply to bpf_skb_net_shrink too. increase gso_size may be no problem and we can use BPF_F_ADJ_ROOM_FIXED_GSO to avoid update gso_size when shrink. > > Not sure that it is okay to linearize inside a BPF helper function. > Hopefully bpf experts can chime in on that. Thanks Fred Li ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v3] net: linearizing skb when downgrade gso_size 2024-07-06 14:26 ` Willem de Bruijn 2024-07-08 14:31 ` [PATCH] net: linearizing skb when downgrade gso_size Fred Li @ 2024-07-17 5:35 ` Fred Li 2024-07-17 16:32 ` Willem de Bruijn 2024-07-19 2:46 ` [PATCH v4] bpf: Fixed a segment issue " Fred Li 2024-07-22 3:08 ` [PATCH bpf v5] bpf: Fixed " Fred Li 3 siblings, 1 reply; 23+ messages in thread From: Fred Li @ 2024-07-17 5:35 UTC (permalink / raw) To: pabeni, willemdebruijn.kernel, herbert Cc: bpf, netdev, linux-kernel, ast, daniel, andrii, song, yonghong.song, john.fastabend, kpsingh, Fred Li Linearizing skb when downgrade gso_size because it may trigger the BUG_ON when segment skb as described in [1]. v3 changes: linearize skb if having frag_list as Willem de Bruijn suggested[2]. [1] https://lore.kernel.org/all/20240626065555.35460-2-dracodingfly@gmail.com/ [2] https://lore.kernel.org/all/668d5cf1ec330_1c18c32947@willemb.c.googlers.com.notmuch/ Signed-off-by: Fred Li <dracodingfly@gmail.com> --- net/core/filter.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index df4578219e82..70919b532d68 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3525,13 +3525,21 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, if (skb_is_gso(skb)) { struct skb_shared_info *shinfo = skb_shinfo(skb); - /* Due to header grow, MSS needs to be downgraded. */ - if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) - skb_decrease_gso_size(shinfo, len_diff); - /* Header must be checked, and gso_segs recomputed. */ shinfo->gso_type |= gso_type; shinfo->gso_segs = 0; + + /* Due to header grow, MSS needs to be downgraded. + * There is BUG_ON When segment the frag_list with + * head_frag true so linearize skb after downgrade + * the MSS. + */ + if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) { + skb_decrease_gso_size(shinfo, len_diff); + if (shinfo->frag_list) + return skb_linearize(skb); + } + } return 0; -- 2.33.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v3] net: linearizing skb when downgrade gso_size 2024-07-17 5:35 ` [PATCH v3] " Fred Li @ 2024-07-17 16:32 ` Willem de Bruijn 2024-07-18 7:42 ` Fred Li 0 siblings, 1 reply; 23+ messages in thread From: Willem de Bruijn @ 2024-07-17 16:32 UTC (permalink / raw) To: Fred Li, pabeni, willemdebruijn.kernel, herbert Cc: bpf, netdev, linux-kernel, ast, daniel, andrii, song, yonghong.song, john.fastabend, kpsingh, Fred Li Fred Li wrote: > Linearizing skb when downgrade gso_size because it may > trigger the BUG_ON when segment skb as described in [1]. > > v3 changes: > linearize skb if having frag_list as Willem de Bruijn suggested[2]. > > [1] https://lore.kernel.org/all/20240626065555.35460-2-dracodingfly@gmail.com/ > [2] https://lore.kernel.org/all/668d5cf1ec330_1c18c32947@willemb.c.googlers.com.notmuch/ > > Signed-off-by: Fred Li <dracodingfly@gmail.com> A fix needs a Fixed tag. This might be the original commit that introduced gso_size adjustment, commit 6578171a7ff0c ("bpf: add bpf_skb_change_proto helper") Unless support for frag_list came later. > --- > net/core/filter.c | 16 ++++++++++++---- > 1 file changed, 12 insertions(+), 4 deletions(-) > > diff --git a/net/core/filter.c b/net/core/filter.c > index df4578219e82..70919b532d68 100644 > --- a/net/core/filter.c > +++ b/net/core/filter.c > @@ -3525,13 +3525,21 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, > if (skb_is_gso(skb)) { > struct skb_shared_info *shinfo = skb_shinfo(skb); > > - /* Due to header grow, MSS needs to be downgraded. */ > - if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) > - skb_decrease_gso_size(shinfo, len_diff); > - > /* Header must be checked, and gso_segs recomputed. */ > shinfo->gso_type |= gso_type; > shinfo->gso_segs = 0; > + > + /* Due to header grow, MSS needs to be downgraded. > + * There is BUG_ON When segment the frag_list with > + * head_frag true so linearize skb after downgrade > + * the MSS. > + */ Super tiny nit: no capitalization of When in the middle of a sentence. > + if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) { > + skb_decrease_gso_size(shinfo, len_diff); > + if (shinfo->frag_list) > + return skb_linearize(skb); I previously asked whether it was safe to call pskb_expand_head from within a BPF external function. There are actually plenty of existing examples of this, so this is fine. > + } > + > } > > return 0; > -- > 2.33.0 > ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v3] net: linearizing skb when downgrade gso_size 2024-07-17 16:32 ` Willem de Bruijn @ 2024-07-18 7:42 ` Fred Li 0 siblings, 0 replies; 23+ messages in thread From: Fred Li @ 2024-07-18 7:42 UTC (permalink / raw) To: willemdebruijn.kernel Cc: andrii, ast, bpf, daniel, dracodingfly, herbert, john.fastabend, kpsingh, linux-kernel, netdev, pabeni, song, yonghong.song > > > Linearizing skb when downgrade gso_size because it may > > trigger the BUG_ON when segment skb as described in [1]. > > > > v3 changes: > > linearize skb if having frag_list as Willem de Bruijn suggested[2]. > > > > [1] https://lore.kernel.org/all/20240626065555.35460-2-dracodingfly@gmail.com/ > > [2] https://lore.kernel.org/all/668d5cf1ec330_1c18c32947@willemb.c.googlers.com.notmuch/ > > > > Signed-off-by: Fred Li <dracodingfly@gmail.com> > > A fix needs a Fixed tag. > > This might be the original commit that introduced gso_size adjustment, > commit 6578171a7ff0c ("bpf: add bpf_skb_change_proto helper") > Yes, this is the original commit, but it's already fixed by commit 364745fbe981a (bpf: Do not change gso_size during bpf_skb_change_proto()) Another commit 2be7e212d5419 (bpf: add bpf_skb_adjust_room helper) introduced gso_size too. > Unless support for frag_list came later. > > > --- > > net/core/filter.c | 16 ++++++++++++---- > > 1 file changed, 12 insertions(+), 4 deletions(-) > > > > diff --git a/net/core/filter.c b/net/core/filter.c > > index df4578219e82..70919b532d68 100644 > > --- a/net/core/filter.c > > +++ b/net/core/filter.c > > @@ -3525,13 +3525,21 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, > > if (skb_is_gso(skb)) { > > struct skb_shared_info *shinfo = skb_shinfo(skb); > > > > - /* Due to header grow, MSS needs to be downgraded. */ > > - if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) > > - skb_decrease_gso_size(shinfo, len_diff); > > - > > /* Header must be checked, and gso_segs recomputed. */ > > shinfo->gso_type |= gso_type; > > shinfo->gso_segs = 0; > > + > > + /* Due to header grow, MSS needs to be downgraded. > > + * There is BUG_ON When segment the frag_list with > > + * head_frag true so linearize skb after downgrade > > + * the MSS. > > + */ > > Super tiny nit: no capitalization of When in the middle of a sentence. Thanks, i'will fix. > > > + if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) { > > + skb_decrease_gso_size(shinfo, len_diff); > > + if (shinfo->frag_list) > > + return skb_linearize(skb); > > I previously asked whether it was safe to call pskb_expand_head from > within a BPF external function. There are actually plenty of existing > examples of this, so this is fine. > > > + } > > + > > } > > > > return 0; > > -- > > 2.33.0 > > ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4] bpf: Fixed a segment issue when downgrade gso_size 2024-07-06 14:26 ` Willem de Bruijn 2024-07-08 14:31 ` [PATCH] net: linearizing skb when downgrade gso_size Fred Li 2024-07-17 5:35 ` [PATCH v3] " Fred Li @ 2024-07-19 2:46 ` Fred Li 2024-07-19 18:22 ` Willem de Bruijn 2024-07-23 1:12 ` bot+bpf-ci 2024-07-22 3:08 ` [PATCH bpf v5] bpf: Fixed " Fred Li 3 siblings, 2 replies; 23+ messages in thread From: Fred Li @ 2024-07-19 2:46 UTC (permalink / raw) To: willemdebruijn.kernel Cc: andrii, ast, bpf, daniel, dracodingfly, herbert, john.fastabend, kpsingh, linux-kernel, netdev, pabeni, song, yonghong.song Linearizing skb when downgrade gso_size because it may trigger the BUG_ON when segment skb as described in [1]. v4 changes: add fixed tag. v3 changes: linearize skb if having frag_list as Willem de Bruijn suggested[2]. [1] https://lore.kernel.org/all/20240626065555.35460-2-dracodingfly@gmail.com/ [2] https://lore.kernel.org/all/668d5cf1ec330_1c18c32947@willemb.c.googlers.com.notmuch/ Fixes: 2be7e212d5419 ("bpf: add bpf_skb_adjust_room helper") Signed-off-by: Fred Li <dracodingfly@gmail.com> --- net/core/filter.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index df4578219e82..71396ecfc574 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3525,13 +3525,21 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, if (skb_is_gso(skb)) { struct skb_shared_info *shinfo = skb_shinfo(skb); - /* Due to header grow, MSS needs to be downgraded. */ - if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) - skb_decrease_gso_size(shinfo, len_diff); - /* Header must be checked, and gso_segs recomputed. */ shinfo->gso_type |= gso_type; shinfo->gso_segs = 0; + + /* Due to header grow, MSS needs to be downgraded. + * There is BUG_ON when segment the frag_list with + * head_frag true so linearize skb after downgrade + * the MSS. + */ + if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) { + skb_decrease_gso_size(shinfo, len_diff); + if (shinfo->frag_list) + return skb_linearize(skb); + } + } return 0; -- 2.33.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v4] bpf: Fixed a segment issue when downgrade gso_size 2024-07-19 2:46 ` [PATCH v4] bpf: Fixed a segment issue " Fred Li @ 2024-07-19 18:22 ` Willem de Bruijn 2024-07-23 1:12 ` bot+bpf-ci 1 sibling, 0 replies; 23+ messages in thread From: Willem de Bruijn @ 2024-07-19 18:22 UTC (permalink / raw) To: Fred Li Cc: andrii, ast, bpf, daniel, herbert, john.fastabend, kpsingh, linux-kernel, netdev, pabeni, song, yonghong.song On Thu, Jul 18, 2024 at 7:47 PM Fred Li <dracodingfly@gmail.com> wrote: > > Linearizing skb when downgrade gso_size because it may > trigger the BUG_ON when segment skb as described in [1]. > > v4 changes: > add fixed tag. > > v3 changes: > linearize skb if having frag_list as Willem de Bruijn suggested[2]. > > [1] https://lore.kernel.org/all/20240626065555.35460-2-dracodingfly@gmail.com/ > [2] https://lore.kernel.org/all/668d5cf1ec330_1c18c32947@willemb.c.googlers.com.notmuch/ > > Fixes: 2be7e212d5419 ("bpf: add bpf_skb_adjust_room helper") > Signed-off-by: Fred Li <dracodingfly@gmail.com> Reviewed-by: Willem de Bruijn <willemb@google.com> For next time: - add target: [PATCH bpf] - use imperative mood in commit messages: "Linearize ..." https://www.kernel.org/doc/Documentation/bpf/bpf_devel_QA.rst https://www.kernel.org/doc/Documentation/process/submitting-patches.rst > --- > net/core/filter.c | 16 ++++++++++++---- > 1 file changed, 12 insertions(+), 4 deletions(-) > > diff --git a/net/core/filter.c b/net/core/filter.c > index df4578219e82..71396ecfc574 100644 > --- a/net/core/filter.c > +++ b/net/core/filter.c > @@ -3525,13 +3525,21 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, > if (skb_is_gso(skb)) { > struct skb_shared_info *shinfo = skb_shinfo(skb); > > - /* Due to header grow, MSS needs to be downgraded. */ > - if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) > - skb_decrease_gso_size(shinfo, len_diff); > - > /* Header must be checked, and gso_segs recomputed. */ > shinfo->gso_type |= gso_type; > shinfo->gso_segs = 0; > + > + /* Due to header grow, MSS needs to be downgraded. > + * There is BUG_ON when segment the frag_list with > + * head_frag true so linearize skb after downgrade > + * the MSS. > + */ > + if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) { > + skb_decrease_gso_size(shinfo, len_diff); > + if (shinfo->frag_list) > + return skb_linearize(skb); > + } > + > } > > return 0; > -- > 2.33.0 > ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v4] bpf: Fixed a segment issue when downgrade gso_size 2024-07-19 2:46 ` [PATCH v4] bpf: Fixed a segment issue " Fred Li 2024-07-19 18:22 ` Willem de Bruijn @ 2024-07-23 1:12 ` bot+bpf-ci 1 sibling, 0 replies; 23+ messages in thread From: bot+bpf-ci @ 2024-07-23 1:12 UTC (permalink / raw) To: dracodingfly; +Cc: bpf, kernel-ci [-- Attachment #1: Type: text/plain, Size: 3138 bytes --] Dear patch submitter, CI has tested the following submission: Status: FAILURE Name: [v4] bpf: Fixed a segment issue when downgrade gso_size Patchwork: https://patchwork.kernel.org/project/netdevbpf/list/?series=872394&state=* Matrix: https://github.com/kernel-patches/bpf/actions/runs/10050697643 Failed jobs: test_progs_no_alu32-aarch64-gcc: https://github.com/kernel-patches/bpf/actions/runs/10050697643/job/27779246113 test_progs_no_alu32-s390x-gcc: https://github.com/kernel-patches/bpf/actions/runs/10050697643/job/27779299595 test_progs_no_alu32-x86_64-gcc: https://github.com/kernel-patches/bpf/actions/runs/10050697643/job/27779290704 test_progs_no_alu32-x86_64-llvm-17: https://github.com/kernel-patches/bpf/actions/runs/10050697643/job/27779296439 test_progs_no_alu32-x86_64-llvm-18: https://github.com/kernel-patches/bpf/actions/runs/10050697643/job/27779303677 First test_progs failure (test_progs_no_alu32-aarch64-gcc): #134 libbpf_get_fd_by_id_opts libbpf: prog 'check_access': BPF program load failed: Invalid argument libbpf: prog 'check_access': -- BEGIN PROG LOAD LOG -- 0: R1=ctx() R10=fp0 ; int BPF_PROG(check_access, struct bpf_map *map, fmode_t fmode) @ test_libbpf_get_fd_by_id_opts.c:27 0: (b7) r0 = 0 ; R0_w=0 1: (79) r2 = *(u64 *)(r1 +0) func 'bpf_lsm_bpf_map' arg0 has btf_id 2072 type STRUCT 'bpf_map' 2: R1=ctx() R2_w=trusted_ptr_bpf_map() ; if (map != (struct bpf_map *)&data_input) @ test_libbpf_get_fd_by_id_opts.c:29 2: (18) r3 = 0xffff0000c3462600 ; R3_w=map_ptr(map=data_input,ks=4,vs=4) 4: (5d) if r2 != r3 goto pc+4 ; R2_w=trusted_ptr_bpf_map() R3_w=map_ptr(map=data_input,ks=4,vs=4) ; int BPF_PROG(check_access, struct bpf_map *map, fmode_t fmode) @ test_libbpf_get_fd_by_id_opts.c:27 5: (79) r0 = *(u64 *)(r1 +8) ; R0_w=scalar() R1=ctx() ; if (fmode & FMODE_WRITE) @ test_libbpf_get_fd_by_id_opts.c:32 6: (67) r0 <<= 62 ; R0_w=scalar(smax=0x4000000000000000,umax=0xc000000000000000,smin32=0,smax32=umax32=0,var_off=(0x0; 0xc000000000000000)) 7: (c7) r0 s>>= 63 ; R0_w=scalar(smin=smin32=-1,smax=smax32=0) ; @ test_libbpf_get_fd_by_id_opts.c:0 8: (57) r0 &= -13 ; R0_w=scalar(smax=0x7ffffffffffffff3,umax=0xfffffffffffffff3,smax32=0x7ffffff3,umax32=0xfffffff3,var_off=(0x0; 0xfffffffffffffff3)) ; int BPF_PROG(check_access, struct bpf_map *map, fmode_t fmode) @ test_libbpf_get_fd_by_id_opts.c:27 9: (95) exit At program exit the register R0 has smax=9223372036854775795 should have been in [-4095, 0] processed 9 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0 -- END PROG LOAD LOG -- libbpf: prog 'check_access': failed to load: -22 libbpf: failed to load object 'test_libbpf_get_fd_by_id_opts' libbpf: failed to load BPF skeleton 'test_libbpf_get_fd_by_id_opts': -22 test_libbpf_get_fd_by_id_opts:FAIL:test_libbpf_get_fd_by_id_opts__open_and_load unexpected error: -22 Please note: this email is coming from an unmonitored mailbox. If you have questions or feedback, please reach out to the Meta Kernel CI team at kernel-ci@meta.com. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH bpf v5] bpf: Fixed segment issue when downgrade gso_size 2024-07-06 14:26 ` Willem de Bruijn ` (2 preceding siblings ...) 2024-07-19 2:46 ` [PATCH v4] bpf: Fixed a segment issue " Fred Li @ 2024-07-22 3:08 ` Fred Li 2024-07-22 3:34 ` bot+bpf-ci 2024-07-22 16:29 ` Willem de Bruijn 3 siblings, 2 replies; 23+ messages in thread From: Fred Li @ 2024-07-22 3:08 UTC (permalink / raw) To: willemdebruijn.kernel Cc: andrii, ast, bpf, daniel, herbert, john.fastabend, kpsingh, linux-kernel, netdev, pabeni, song, yonghong.song, Fred Li Linearize skb when downgrad gso_size to prevent triggering the BUG_ON during segment skb as described in [1]. v5 changes: - add bpf subject prefix. - adjust message to imperative mood. v4 changes: - add fixed tag. v3 changes: - linearize skb if having frag_list as Willem de Bruijn suggested [2]. [1] https://lore.kernel.org/all/20240626065555.35460-2-dracodingfly@gmail.com/ [2] https://lore.kernel.org/all/668d5cf1ec330_1c18c32947@willemb.c.googlers.com.notmuch/ Fixes: 2be7e212d541 ("bpf: add bpf_skb_adjust_room helper") Signed-off-by: Fred Li <dracodingfly@gmail.com> --- net/core/filter.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index df4578219e82..71396ecfc574 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3525,13 +3525,21 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, if (skb_is_gso(skb)) { struct skb_shared_info *shinfo = skb_shinfo(skb); - /* Due to header grow, MSS needs to be downgraded. */ - if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) - skb_decrease_gso_size(shinfo, len_diff); - /* Header must be checked, and gso_segs recomputed. */ shinfo->gso_type |= gso_type; shinfo->gso_segs = 0; + + /* Due to header grow, MSS needs to be downgraded. + * There is BUG_ON when segment the frag_list with + * head_frag true so linearize skb after downgrade + * the MSS. + */ + if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) { + skb_decrease_gso_size(shinfo, len_diff); + if (shinfo->frag_list) + return skb_linearize(skb); + } + } return 0; -- 2.33.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH bpf v5] bpf: Fixed segment issue when downgrade gso_size 2024-07-22 3:08 ` [PATCH bpf v5] bpf: Fixed " Fred Li @ 2024-07-22 3:34 ` bot+bpf-ci 2024-07-22 16:29 ` Willem de Bruijn 1 sibling, 0 replies; 23+ messages in thread From: bot+bpf-ci @ 2024-07-22 3:34 UTC (permalink / raw) To: dracodingfly; +Cc: bpf, kernel-ci [-- Attachment #1: Type: text/plain, Size: 528 bytes --] Dear patch submitter, CI has tested the following submission: Status: SUCCESS Name: [bpf,v5] bpf: Fixed segment issue when downgrade gso_size Patchwork: https://patchwork.kernel.org/project/netdevbpf/list/?series=872810&state=* Matrix: https://github.com/kernel-patches/bpf/actions/runs/10034064977 No further action is necessary on your part. Please note: this email is coming from an unmonitored mailbox. If you have questions or feedback, please reach out to the Meta Kernel CI team at kernel-ci@meta.com. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH bpf v5] bpf: Fixed segment issue when downgrade gso_size 2024-07-22 3:08 ` [PATCH bpf v5] bpf: Fixed " Fred Li 2024-07-22 3:34 ` bot+bpf-ci @ 2024-07-22 16:29 ` Willem de Bruijn 2024-07-24 13:37 ` Fred Li 1 sibling, 1 reply; 23+ messages in thread From: Willem de Bruijn @ 2024-07-22 16:29 UTC (permalink / raw) To: Fred Li Cc: andrii, ast, bpf, daniel, herbert, john.fastabend, kpsingh, linux-kernel, netdev, pabeni, song, yonghong.song On Sun, Jul 21, 2024 at 8:08 PM Fred Li <dracodingfly@gmail.com> wrote: > > Linearize skb when downgrad gso_size to prevent triggering > the BUG_ON during segment skb as described in [1]. > > v5 changes: > - add bpf subject prefix. > - adjust message to imperative mood. > > v4 changes: > - add fixed tag. > > v3 changes: > - linearize skb if having frag_list as Willem de Bruijn suggested [2]. > > [1] https://lore.kernel.org/all/20240626065555.35460-2-dracodingfly@gmail.com/ > [2] https://lore.kernel.org/all/668d5cf1ec330_1c18c32947@willemb.c.googlers.com.notmuch/ > > Fixes: 2be7e212d541 ("bpf: add bpf_skb_adjust_room helper") > Signed-off-by: Fred Li <dracodingfly@gmail.com> Reviewed-by: Willem de Bruijn <willemb@google.com> My comments were informational, for a next patch if any, really. v4 was fine. v5 is too. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH bpf v5] bpf: Fixed segment issue when downgrade gso_size 2024-07-22 16:29 ` Willem de Bruijn @ 2024-07-24 13:37 ` Fred Li 2024-07-25 10:09 ` Daniel Borkmann 0 siblings, 1 reply; 23+ messages in thread From: Fred Li @ 2024-07-24 13:37 UTC (permalink / raw) To: willemdebruijn.kernel; +Cc: bpf, linux-kernel, netdev > > > > Linearize skb when downgrad gso_size to prevent triggering > > the BUG_ON during segment skb as described in [1]. > > > > v5 changes: > > - add bpf subject prefix. > > - adjust message to imperative mood. > > > > v4 changes: > > - add fixed tag. > > > > v3 changes: > > - linearize skb if having frag_list as Willem de Bruijn suggested [2]. > > > > [1] https://lore.kernel.org/all/20240626065555.35460-2-dracodingfly@gmail.com/ > > [2] https://lore.kernel.org/all/668d5cf1ec330_1c18c32947@willemb.c.googlers.com.notmuch/ > > > > Fixes: 2be7e212d541 ("bpf: add bpf_skb_adjust_room helper") > > Signed-off-by: Fred Li <dracodingfly@gmail.com> > > Reviewed-by: Willem de Bruijn <willemb@google.com> > > My comments were informational, for a next patch if any, really. v4 > was fine. v5 is too. Thanks for your advise. Fred Li ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH bpf v5] bpf: Fixed segment issue when downgrade gso_size 2024-07-24 13:37 ` Fred Li @ 2024-07-25 10:09 ` Daniel Borkmann 0 siblings, 0 replies; 23+ messages in thread From: Daniel Borkmann @ 2024-07-25 10:09 UTC (permalink / raw) To: Fred Li, willemdebruijn.kernel; +Cc: bpf, linux-kernel, netdev On 7/24/24 3:37 PM, Fred Li wrote: >>> >>> Linearize skb when downgrad gso_size to prevent triggering >>> the BUG_ON during segment skb as described in [1]. >>> >>> v5 changes: >>> - add bpf subject prefix. >>> - adjust message to imperative mood. >>> >>> v4 changes: >>> - add fixed tag. >>> >>> v3 changes: >>> - linearize skb if having frag_list as Willem de Bruijn suggested [2]. >>> >>> [1] https://lore.kernel.org/all/20240626065555.35460-2-dracodingfly@gmail.com/ >>> [2] https://lore.kernel.org/all/668d5cf1ec330_1c18c32947@willemb.c.googlers.com.notmuch/ >>> >>> Fixes: 2be7e212d541 ("bpf: add bpf_skb_adjust_room helper") >>> Signed-off-by: Fred Li <dracodingfly@gmail.com> >> >> Reviewed-by: Willem de Bruijn <willemb@google.com> >> >> My comments were informational, for a next patch if any, really. v4 >> was fine. v5 is too. > > Thanks for your advise. > > Fred Li lgtm, I slightly improved wording & applied, thanks! ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 0/2] net: Fix BUG_ON for segment frag_list with mangled gso_size and head_frag is true 2024-06-26 6:55 [PATCH v2 2/2] test_bpf: Introduce an skb_segment test for frag_list whose head_frag=true and gso_size was mangled Fred Li 2024-06-26 6:55 ` [PATCH v2 1/2] net: Fix skb_segment when splitting gso_size mangled skb having linear-headed frag_list whose head_frag=true Fred Li @ 2024-06-26 6:55 ` Fred Li 1 sibling, 0 replies; 23+ messages in thread From: Fred Li @ 2024-06-26 6:55 UTC (permalink / raw) To: davem, edumazet, kuba, pabeni, aleksander.lobakin, sashal, linux, hawk, nbd, mkhalfella, ast, daniel, andrii, martin.lau, song, yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa Cc: netdev, linux-kernel, bpf, Fred Li This serices fix the BUG_ON when segment frag_list with mangled gso_size and head_frag is true. This patch was tested on kernel 6.6.35. v2 changes: Updated with remove the sg condition may be more make sense. Fred Li (2): net: Fix skb_segment when splitting gso_size mangled skb having linear-headed frag_list whose head_frag=true test_bpf: Introduce an skb_segment test for frag_list whose head_frag=true and gso_size was mangled lib/test_bpf.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ net/core/skbuff.c | 2 +- 2 files changed, 65 insertions(+), 1 deletion(-) -- 2.33.0 ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2024-07-25 10:09 UTC | newest] Thread overview: 23+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-06-26 6:55 [PATCH v2 2/2] test_bpf: Introduce an skb_segment test for frag_list whose head_frag=true and gso_size was mangled Fred Li 2024-06-26 6:55 ` [PATCH v2 1/2] net: Fix skb_segment when splitting gso_size mangled skb having linear-headed frag_list whose head_frag=true Fred Li 2024-07-02 9:23 ` Paolo Abeni 2024-07-03 12:21 ` Fred Li 2024-07-06 14:26 ` Willem de Bruijn 2024-07-08 14:31 ` [PATCH] net: linearizing skb when downgrade gso_size Fred Li 2024-07-09 15:53 ` Willem de Bruijn 2024-07-09 20:16 ` Herbert Xu 2024-07-09 21:29 ` Willem de Bruijn 2024-07-10 23:06 ` Herbert Xu 2024-07-12 8:17 ` Fred Li 2024-07-17 5:35 ` [PATCH v3] " Fred Li 2024-07-17 16:32 ` Willem de Bruijn 2024-07-18 7:42 ` Fred Li 2024-07-19 2:46 ` [PATCH v4] bpf: Fixed a segment issue " Fred Li 2024-07-19 18:22 ` Willem de Bruijn 2024-07-23 1:12 ` bot+bpf-ci 2024-07-22 3:08 ` [PATCH bpf v5] bpf: Fixed " Fred Li 2024-07-22 3:34 ` bot+bpf-ci 2024-07-22 16:29 ` Willem de Bruijn 2024-07-24 13:37 ` Fred Li 2024-07-25 10:09 ` Daniel Borkmann 2024-06-26 6:55 ` [PATCH v2 0/2] net: Fix BUG_ON for segment frag_list with mangled gso_size and head_frag is true Fred Li
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).