Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
net: Fix the gso BUG_ON that treat the skb which head_frag is true as…
… non head_frag The crashed kernel version is 5.16.20, and I have not test this patch because I dont find a way to reproduce it, and the mailine may be has the same problem. When using bpf based NAT, hits a kernel BUG_ON at function skb_segment(), BUG_ON(skb_headlen(list_skb) > len). The bpf calls the bpf_skb_adjust_room to decrease the gso_size, and then call bpf_redirect send packet out. 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 kernel-patches#9 [ffffa3f2cce08720] skb_segment at ffffffffb97ded63 kernel-patches#10 [ffffa3f2cce08800] tcp_gso_segment at ffffffffb98d0320 kernel-patches#11 [ffffa3f2cce08860] tcp4_gso_segment at ffffffffb98d07a3 kernel-patches#12 [ffffa3f2cce08880] inet_gso_segment at ffffffffb98e6de0 kernel-patches#13 [ffffa3f2cce088e0] skb_mac_gso_segment at ffffffffb97f3741 kernel-patches#14 [ffffa3f2cce08918] skb_udp_tunnel_segment at ffffffffb98daa59 kernel-patches#15 [ffffa3f2cce08980] udp4_ufo_fragment at ffffffffb98db471 kernel-patches#16 [ffffa3f2cce089b0] inet_gso_segment at ffffffffb98e6de0 kernel-patches#17 [ffffa3f2cce08a10] skb_mac_gso_segment at ffffffffb97f3741 kernel-patches#18 [ffffa3f2cce08a48] __skb_gso_segment at ffffffffb97f388e kernel-patches#19 [ffffa3f2cce08a78] validate_xmit_skb at ffffffffb97f3d6e kernel-patches#20 [ffffa3f2cce08ab8] __dev_queue_xmit at ffffffffb97f4614 kernel-patches#21 [ffffa3f2cce08b50] dev_queue_xmit at ffffffffb97f5030 kernel-patches#22 [ffffa3f2cce08b60] __bpf_redirect at ffffffffb98199a8 kernel-patches#23 [ffffa3f2cce08b88] skb_do_redirect at ffffffffb98205cd ... 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 3962 struct sk_buff *skb_segment(struct sk_buff *head_skb, 3963 netdev_features_t features) 3964 { 3965 struct sk_buff *segs = NULL; 3966 struct sk_buff *tail = NULL; ... 4181 while (pos < offset + len) { 4182 if (i >= nfrags) { 4183 i = 0; 4184 nfrags = skb_shinfo(list_skb)->nr_frags; 4185 frag = skb_shinfo(list_skb)->frags; 4186 frag_skb = list_skb; After segment the head_skb's last frag, the (pos == offset+len), so break the while at line 4181, run into this BUG_ON(), not segment the head_frag frag_list skb. Since commit 13acc94(net: permit skb_segment on head_frag frag_list skb), it is allowed to segment the head_frag frag_list skb. In commit 3dcbdb1 (net: gso: Fix skb_segment splat when splitting gso_size mangled skb having linear-headed frag_list), it is cleared the NETIF_F_SG if it has non head_frag skb. It is not cleared the NETIF_F_SG only with one head_frag frag_list skb. Signed-off-by: Fred Li <dracodingfly@gmail.com> Signed-off-by: NipaLocal <nipa@local>
- Loading branch information