Using GSO in the UDP path on a device with scatter-gather netdevice feature disabled will result in a kernel panic with the following call stack:
kernel BUG at net/core/skbuff.c:104! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP PC is at skb_panic+0x4c/0x54 LR is at skb_panic+0x4c/0x54 Process udpgso_bench_tx (pid: 4078, stack limit = 0xffffff8048de8000) [<ffffff96e8790378>] skb_panic+0x4c/0x54 [<ffffff96e8788b54>] skb_copy_bits+0x0/0x244 [<ffffff96e8836088>] __ip_append_data+0x230/0x814 [<ffffff96e8837090>] ip_make_skb+0xe4/0x178 [<ffffff96e8865444>] udp_sendmsg+0x828/0x888 [<ffffff96e8872818>] inet_sendmsg+0xe4/0x130 [<ffffff96e877c894>] ___sys_sendmsg+0x1d8/0x2c0 [<ffffff96e877ca0c>] SyS_sendmsg+0x90/0xe0 This panic is the result of allocating SKBs with small size for the newly segmented SKB. If the scatter-gather feature is disabled, the code attempts to call skb_put() on the small SKB with an argument of nearly the entire unsegmented SKB length. After this patch, attempting to use GSO with scatter-gather disabled will result in -EINVAL being returned. Fixes: 15e36f5b8e98 ("udp: paged allocation with gso") Signed-off-by: Sean Tranchetti <stran...@codeaurora.org> Signed-off-by: Subash Abhinov Kasiviswanathan <subas...@codeaurora.org> --- net/ipv4/ip_output.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index b5e21eb..0d63690 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1054,8 +1054,16 @@ static int __ip_append_data(struct sock *sk, copy = length; if (!(rt->dst.dev->features&NETIF_F_SG)) { + struct sk_buff *tmp; unsigned int off; + if (paged) { + err = -EINVAL; + while ((tmp = __skb_dequeue(queue)) != NULL) + kfree(tmp); + goto error; + } + off = skb->len; if (getfrag(from, skb_put(skb, copy), offset, copy, off, skb) < 0) { -- 1.9.1