提交 94d51684 编写于 作者: L lena wang 提交者: Zheng Zengkai

net: fix up skbs delta_truesize in UDP GRO frag_list

stable inclusion
from stable-v5.10.104
commit 4e178ed14bda47942c1ccad3f60b774870b45db9
bugzilla: https://gitee.com/openeuler/kernel/issues/I56XAC

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4e178ed14bda47942c1ccad3f60b774870b45db9

--------------------------------

commit 224102de upstream.

The truesize for a UDP GRO packet is added by main skb and skbs in main
skb's frag_list:
skb_gro_receive_list
        p->truesize += skb->truesize;

The commit 53475c5d ("net: fix use-after-free when UDP GRO with
shared fraglist") introduced a truesize increase for frag_list skbs.
When uncloning skb, it will call pskb_expand_head and trusesize for
frag_list skbs may increase. This can occur when allocators uses
__netdev_alloc_skb and not jump into __alloc_skb. This flow does not
use ksize(len) to calculate truesize while pskb_expand_head uses.
skb_segment_list
err = skb_unclone(nskb, GFP_ATOMIC);
pskb_expand_head
        if (!skb->sk || skb->destructor == sock_edemux)
                skb->truesize += size - osize;

If we uses increased truesize adding as delta_truesize, it will be
larger than before and even larger than previous total truesize value
if skbs in frag_list are abundant. The main skb truesize will become
smaller and even a minus value or a huge value for an unsigned int
parameter. Then the following memory check will drop this abnormal skb.

To avoid this error we should use the original truesize to segment the
main skb.

Fixes: 53475c5d ("net: fix use-after-free when UDP GRO with shared fraglist")
Signed-off-by: Nlena wang <lena.wang@mediatek.com>
Acked-by: NPaolo Abeni <pabeni@redhat.com>
Reviewed-by: NEric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/1646133431-8948-1-git-send-email-lena.wang@mediatek.comSigned-off-by: NJakub Kicinski <kuba@kernel.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NYu Liao <liaoyu15@huawei.com>
Reviewed-by: NWei Li <liwei391@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 cc3dd405
...@@ -3695,6 +3695,7 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb, ...@@ -3695,6 +3695,7 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
list_skb = list_skb->next; list_skb = list_skb->next;
err = 0; err = 0;
delta_truesize += nskb->truesize;
if (skb_shared(nskb)) { if (skb_shared(nskb)) {
tmp = skb_clone(nskb, GFP_ATOMIC); tmp = skb_clone(nskb, GFP_ATOMIC);
if (tmp) { if (tmp) {
...@@ -3719,7 +3720,6 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb, ...@@ -3719,7 +3720,6 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
tail = nskb; tail = nskb;
delta_len += nskb->len; delta_len += nskb->len;
delta_truesize += nskb->truesize;
skb_push(nskb, -skb_network_offset(nskb) + offset); skb_push(nskb, -skb_network_offset(nskb) + offset);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册