From: Shiming Cheng <[email protected]>
A SKB_GSO_FRAGLIST skb without GSO_BY_FRAGS is
expected to have all segments except the last
to be gso_size long. If this does not hold, the
skb has been modified and the fraglist gso integrity
is lost. Drop the packet, as it cannot be segmented
correctly by skb_segment_list.
The skb could be salvaged. By linearizing, dropping
the SKB_GSO_FRAGLIST bit and entering the normal
skb_segment path rather than the skb_segment_list path.
That choice is currently made in the protocol caller,
__udp_gso_segment. It's not trivial to add such a
backup path here. So let's add this backstop against
kernel crashes.
Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.")
Signed-off-by: Shiming Cheng <[email protected]>
Signed-off-by: Lena Wang <[email protected]>
---
net/core/skbuff.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index b99127712e67..4777f5fea6c3 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -4491,6 +4491,7 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
{
struct sk_buff *list_skb = skb_shinfo(skb)->frag_list;
unsigned int tnl_hlen = skb_tnl_header_len(skb);
+ unsigned int mss = skb_shinfo(skb)->gso_size;
unsigned int delta_truesize = 0;
unsigned int delta_len = 0;
struct sk_buff *tail = NULL;
@@ -4504,6 +4505,9 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
if (err)
goto err_linearize;
+ if (mss != GSO_BY_FRAGS && mss != skb_headlen(skb))
+ return ERR_PTR(-EFAULT);
+
skb_shinfo(skb)->frag_list = NULL;
while (list_skb) {
--
2.18.0
shiming.cheng@ wrote:
> From: Shiming Cheng <[email protected]>
>
> A SKB_GSO_FRAGLIST skb without GSO_BY_FRAGS is
> expected to have all segments except the last
> to be gso_size long. If this does not hold, the
> skb has been modified and the fraglist gso integrity
> is lost. Drop the packet, as it cannot be segmented
> correctly by skb_segment_list.
>
> The skb could be salvaged. By linearizing, dropping
> the SKB_GSO_FRAGLIST bit and entering the normal
> skb_segment path rather than the skb_segment_list path.
>
> That choice is currently made in the protocol caller,
> __udp_gso_segment. It's not trivial to add such a
> backup path here. So let's add this backstop against
> kernel crashes.
>
> Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.")
> Signed-off-by: Shiming Cheng <[email protected]>
> Signed-off-by: Lena Wang <[email protected]>
Reviewed-by: Willem de Bruijn <[email protected]>
On Mon, 2024-04-29 at 09:25 -0400, Willem de Bruijn wrote:
>
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> shiming.cheng@ wrote:
> > From: Shiming Cheng <[email protected]>
> >
> > A SKB_GSO_FRAGLIST skb without GSO_BY_FRAGS is
> > expected to have all segments except the last
> > to be gso_size long. If this does not hold, the
> > skb has been modified and the fraglist gso integrity
> > is lost. Drop the packet, as it cannot be segmented
> > correctly by skb_segment_list.
> >
> > The skb could be salvaged. By linearizing, dropping
> > the SKB_GSO_FRAGLIST bit and entering the normal
> > skb_segment path rather than the skb_segment_list path.
> >
> > That choice is currently made in the protocol caller,
> > __udp_gso_segment. It's not trivial to add such a
> > backup path here. So let's add this backstop against
> > kernel crashes.
> >
> > Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.")
> > Signed-off-by: Shiming Cheng <[email protected]>
> > Signed-off-by: Lena Wang <[email protected]>
>
> Reviewed-by: Willem de Bruijn <[email protected]>
Dear experts,
Could you please help to update the upstream progress?
Thanks
Lena
Hello,
kernel test robot noticed "kernel-selftests.net.udpgro_fwd.sh.fail" on:
commit: 7ed67c5ee988b506bd05e115e9e8299bccbabffd ("[PATCH net] net: drop pulled SKB_GSO_FRAGLIST skb")
url: https://github.com/intel-lab-lkp/linux/commits/shiming-cheng-mediatek-com/net-drop-pulled-SKB_GSO_FRAGLIST-skb/20240430-133823
base: https://git.kernel.org/cgit/linux/kernel/git/davem/net.git ba1cb99b559e3b12db8b65ca9ff03358ea318064
patch link: https://lore.kernel.org/all/[email protected]/
patch subject: [PATCH net] net: drop pulled SKB_GSO_FRAGLIST skb
in testcase: kernel-selftests
version: kernel-selftests-x86_64-977d51cf-1_20240508
with following parameters:
group: net
compiler: gcc-13
test machine: 36 threads 1 sockets Intel(R) Core(TM) i9-10980XE CPU @ 3.00GHz (Cascade Lake) with 32G memory
(please refer to attached dmesg/kmsg for entire log/backtrace)
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]>
| Closes: https://lore.kernel.org/oe-lkp/[email protected]
# timeout set to 3600
# selftests: net: udpgro_fwd.sh
# IPv4
# No GRO ok
# GRO frag list ./udpgso_bench_rx: wrong packet number! got 0, expected 10
#
# fail client exit code 0, server 1
# GRO fwd ok
# UDP fwd perf udp tx: 1488 MB/s 25250 calls/s 25250 msg/s
# udp rx: 1 MB/s 1280 calls/s
# udp tx: 1501 MB/s 25471 calls/s 25471 msg/s
# udp rx: 1 MB/s 1280 calls/s
# udp tx: 1512 MB/s 25656 calls/s 25656 msg/s
# udp rx: 1 MB/s 1380 calls/s
# UDP GRO fwd perf udp rx: 337 MB/s 272896 calls/s
# udp tx: 2183 MB/s 37033 calls/s 37033 msg/s
# udp rx: 376 MB/s 304320 calls/s
# udp tx: 2162 MB/s 36675 calls/s 36675 msg/s
# udp rx: 402 MB/s 325376 calls/s
# udp tx: 2167 MB/s 36758 calls/s 36758 msg/s
# GRO frag list over UDP tunnel ok
# GRO fwd over UDP tunnel ok
# IPv6
# No GRO ok
# GRO frag list ./udpgso_bench_rx: wrong packet number! got 0, expected 10
#
# fail client exit code 0, server 1
# GRO fwd ok
# UDP fwd perf udp rx: 37 MB/s 30033 calls/s
# udp tx: 2220 MB/s 37661 calls/s 37661 msg/s
# udp rx: 99 MB/s 80141 calls/s
# udp tx: 2179 MB/s 36973 calls/s 36973 msg/s
# udp tx: 2161 MB/s 36654 calls/s 36654 msg/s
# udp rx: 104 MB/s 84775 calls/s
# UDP GRO fwd perf udp rx: 162 MB/s 131584 calls/s
# udp tx: 2113 MB/s 35848 calls/s 35848 msg/s
# udp rx: 263 MB/s 213370 calls/s
# udp tx: 2097 MB/s 35574 calls/s 35574 msg/s
# udp rx: 217 MB/s 175616 calls/s
# udp tx: 2107 MB/s 35748 calls/s 35748 msg/s
# GRO frag list over UDP tunnel ok
# GRO fwd over UDP tunnel ok
not ok 53 selftests: net: udpgro_fwd.sh # exit=1
The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20240520/[email protected]
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki