diff mbox series

[net-next,V2] net: fix kfree_skb_list use of skb_mark_not_on_list

Message ID 167421088417.1125894.9761158218878962159.stgit@firesoul (mailing list archive)
State Accepted
Commit f72ff8b81ebc6a0a25e41b7e6c1dc42e3aa33e7e
Delegated to: Netdev Maintainers
Headers show
Series [net-next,V2] net: fix kfree_skb_list use of skb_mark_not_on_list | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 2 this patch: 2
netdev/cc_maintainers fail 1 blamed authors not CCed: saeed@kernel.org; 1 maintainers not CCed: saeed@kernel.org
netdev/build_clang success Errors and warnings before: 1 this patch: 1
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 2 this patch: 2
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Jesper Dangaard Brouer Jan. 20, 2023, 10:34 a.m. UTC
A bug was introduced by commit eedade12f4cb ("net: kfree_skb_list use
kmem_cache_free_bulk"). It unconditionally unlinked the SKB list via
invoking skb_mark_not_on_list().

In this patch we choose to remove the skb_mark_not_on_list() call as it
isn't necessary. It would be possible and correct to call
skb_mark_not_on_list() only when __kfree_skb_reason() returns true,
meaning the SKB is ready to be free'ed, as it calls/check skb_unref().

This fix is needed as kfree_skb_list() is also invoked on skb_shared_info
frag_list (skb_drop_fraglist() calling kfree_skb_list()). A frag_list can
have SKBs with elevated refcnt due to cloning via skb_clone_fraglist(),
which takes a reference on all SKBs in the list. This implies the
invariant that all SKBs in the list must have the same refcnt, when using
kfree_skb_list().

Reported-by: syzbot+c8a2e66e37eee553c4fd@syzkaller.appspotmail.com
Reported-and-tested-by: syzbot+c8a2e66e37eee553c4fd@syzkaller.appspotmail.com
Fixes: eedade12f4cb ("net: kfree_skb_list use kmem_cache_free_bulk")
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
 net/core/skbuff.c |    2 --
 1 file changed, 2 deletions(-)

Comments

Eric Dumazet Jan. 20, 2023, 12:40 p.m. UTC | #1
On Fri, Jan 20, 2023 at 11:34 AM Jesper Dangaard Brouer
<brouer@redhat.com> wrote:
>
> A bug was introduced by commit eedade12f4cb ("net: kfree_skb_list use
> kmem_cache_free_bulk"). It unconditionally unlinked the SKB list via
> invoking skb_mark_not_on_list().
>
> In this patch we choose to remove the skb_mark_not_on_list() call as it
> isn't necessary. It would be possible and correct to call
> skb_mark_not_on_list() only when __kfree_skb_reason() returns true,
> meaning the SKB is ready to be free'ed, as it calls/check skb_unref().
>
> This fix is needed as kfree_skb_list() is also invoked on skb_shared_info
> frag_list (skb_drop_fraglist() calling kfree_skb_list()). A frag_list can
> have SKBs with elevated refcnt due to cloning via skb_clone_fraglist(),
> which takes a reference on all SKBs in the list. This implies the
> invariant that all SKBs in the list must have the same refcnt, when using
> kfree_skb_list().
>
> Reported-by: syzbot+c8a2e66e37eee553c4fd@syzkaller.appspotmail.com
> Reported-and-tested-by: syzbot+c8a2e66e37eee553c4fd@syzkaller.appspotmail.com
> Fixes: eedade12f4cb ("net: kfree_skb_list use kmem_cache_free_bulk")
> Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>

Reviewed-by: Eric Dumazet <edumazet@google.com>
patchwork-bot+netdevbpf@kernel.org Jan. 24, 2023, 5:50 a.m. UTC | #2
Hello:

This patch was applied to netdev/net-next.git (master)
by Jakub Kicinski <kuba@kernel.org>:

On Fri, 20 Jan 2023 11:34:44 +0100 you wrote:
> A bug was introduced by commit eedade12f4cb ("net: kfree_skb_list use
> kmem_cache_free_bulk"). It unconditionally unlinked the SKB list via
> invoking skb_mark_not_on_list().
> 
> In this patch we choose to remove the skb_mark_not_on_list() call as it
> isn't necessary. It would be possible and correct to call
> skb_mark_not_on_list() only when __kfree_skb_reason() returns true,
> meaning the SKB is ready to be free'ed, as it calls/check skb_unref().
> 
> [...]

Here is the summary with links:
  - [net-next,V2] net: fix kfree_skb_list use of skb_mark_not_on_list
    https://git.kernel.org/netdev/net-next/c/f72ff8b81ebc

You are awesome, thank you!
diff mbox series

Patch

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4e73ab3482b8..180df58e85c7 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -999,8 +999,6 @@  kfree_skb_list_reason(struct sk_buff *segs, enum skb_drop_reason reason)
 	while (segs) {
 		struct sk_buff *next = segs->next;
 
-		skb_mark_not_on_list(segs);
-
 		if (__kfree_skb_reason(segs, reason))
 			kfree_skb_add_bulk(segs, &sa, reason);