Netdev List
 help / color / mirror / Atom feed
* [PATCH net] net/sched: taprio: unwind the netdevice notifier if register_qdisc() fails
@ 2026-10-21 15:54 Dudu Lu
  2026-10-21 15:58 ` netdev-bot+sinfo
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Dudu Lu @ 2026-10-21 15:54 UTC (permalink / raw)
  To: vinicius.gomes, jhs, jiri; +Cc: netdev

taprio_module_init() registers taprio_device_notifier and then returns
register_qdisc()'s error directly.  When register_qdisc() fails the
notifier stays registered, but the loader's failure path frees the module
image without ever calling the __exit function, so netdev_chain is left
pointing at taprio_device_notifier.notifier_call -- a function pointer
that lives in text that has just been freed.

register_qdisc() has two failure returns: -EEXIST (duplicate .id) and
-EINVAL (malformed cl_ops).  taprio_class_ops satisfies every checked
implication, so -EINVAL is unreachable and -EEXIST is the only reachable
failure; it needs a pre-existing "taprio" entry in qdisc_base.  In-tree
that is reachable only through bpf_qdisc_reg() (CONFIG_NET_SCH_BPF); a
module calling the exported register_qdisc() reaches it as well.

Once the notifier is left dangling, the next netdevice event that walks
netdev_chain calls through the stale pointer:

  BUG: KASAN: vmalloc-out-of-bounds in notifier_call_chain+0x650/0xb5c
  Read of size 8 at addr ffff80001fc5ab08 by task ip/110
   notifier_call_chain+0x650/0xb5c
   raw_notifier_call_chain+0x34/0x64
   call_netdevice_notifiers_info+0xa8/0x198
   __dev_close_many+0xe0/0x800
   ...
  >ffff80001fc5ab00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8

The shadow row is all f8 (KASAN_VMALLOC_INVALID): the read lands in
vmalloc memory that was poisoned when the module image was freed, and the
indirect call is unguarded because the only check, func_ptr_is_kernel_text(),
is compiled out unless CONFIG_DEBUG_NOTIFIERS.

Mirror the sibling sch_cbs.c and act_mirred.c, which unwind the notifier
on this failure path.

Fixes: 7b9eba7ba0c1 ("net/sched: taprio: fix picos_per_byte miscalculation")
Assisted-by: LLM
Signed-off-by: Dudu Lu <phx0fer@gmail.com>
---
Tested base
-----------
Detected on Linux 7.3-rc4 (commit 93f51579e7df), arm64 QEMU guest.
Re-checked against mainline f47d223627f8 (v7.3-341): the affected code
is unchanged between the two, so the bug is still present there.
Checked against linux-next next-20261021 (commit 9a482184d910): the
affected code is unchanged there as well, so the bug is still present in
linux-next too.

Reproducer status
-----------------
A reproducer was written and executed on an arm64 QEMU guest with
CONFIG_NET_SCH_TAPRIO=m, KASAN_VMALLOC=y, CONFIG_MODULE_UNLOAD=y; it fires at the
claimed sink.  The reproducer source is not posted here per
Documentation/process/security-bugs.rst; it is available on request.

Triggering conditions
---------------------
A pre-existing "taprio" entry in qdisc_base, so register_qdisc() returns
-EEXIST (the only reachable failure).  In-tree this is reachable via
bpf_qdisc_reg() (CONFIG_NET_SCH_BPF); the reproducer reaches it through the
exported register_qdisc().  Then a NETDEV_UP event.

Notes
-----
Built and checkpatch-clean: this patch was applied on top of 7.3-rc4
(commit 93f51579e7df) and a full arm64 kernel (defconfig) was built with
it -- no new warnings or errors.  scripts/checkpatch.pl reports 0 errors,
0 warnings.

 net/sched/sch_taprio.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 39ac5b97aa3a..6eb40a379e79 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -2572,7 +2572,11 @@ static int __init taprio_module_init(void)
 	if (err)
 		return err;
 
-	return register_qdisc(&taprio_qdisc_ops);
+	err = register_qdisc(&taprio_qdisc_ops);
+	if (err)
+		unregister_netdevice_notifier(&taprio_device_notifier);
+
+	return err;
 }
 
 static void __exit taprio_module_exit(void)

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net] net/sched: taprio: unwind the netdevice notifier if register_qdisc() fails
  2026-10-21 15:54 [PATCH net] net/sched: taprio: unwind the netdevice notifier if register_qdisc() fails Dudu Lu
@ 2026-10-21 15:58 ` netdev-bot+sinfo
  2026-10-22  4:59   ` phx
  2026-10-23 10:59 ` Simon Horman
  2026-10-26 23:30 ` patchwork-bot+netdevbpf
  2 siblings, 1 reply; 5+ messages in thread
From: netdev-bot+sinfo @ 2026-10-21 15:58 UTC (permalink / raw)
  To: Dudu Lu; +Cc: vinicius.gomes, jhs, jiri, netdev

Hi!

This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:

 - How the issue was discovered, e.g. hit in production, hit during
   development, syzbot report, manual code inspection, LLM or static
   analysis tool scan.

Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.

The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net] net/sched: taprio: unwind the netdevice notifier if register_qdisc() fails
  2026-10-21 15:58 ` netdev-bot+sinfo
@ 2026-10-22  4:59   ` phx
  0 siblings, 0 replies; 5+ messages in thread
From: phx @ 2026-10-22  4:59 UTC (permalink / raw)
  To: netdev-bot+sinfo; +Cc: vinicius.gomes, jhs, jiri, netdev

Hi, The issue was found by LLM-assisted review of this code path (static analysis), not from a production hit or a syzbot report. I then wrote a reproducer and ran it on an arm64 QEMU guest under KASAN; it fired at the claimed sink (notifier_call_chain, vmalloc-out-of-bounds). The "Assisted-by: LLM" trailer reflects that assistance. Thanks.

> 2026年10月21日 下午11:58,netdev-bot+sinfo@kernel.org 写道:
> 
> Hi!
> 
> This is an automated message. This series looks like a fix, but its
> commit messages seem to be missing some information:
> 
> - How the issue was discovered, e.g. hit in production, hit during
>   development, syzbot report, manual code inspection, LLM or static
>   analysis tool scan.
> 
> Please do not repost the series just to address the above. Instead,
> reply to this email with the missing information, so that reviewers
> can take it into account. If the series needs another revision for
> other reasons, please include the information in the commit messages
> then.
> 
> The evaluation is done by an LLM so it may be wrong, if you think
> that is the case please reply and explain.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net] net/sched: taprio: unwind the netdevice notifier if register_qdisc() fails
  2026-10-21 15:54 [PATCH net] net/sched: taprio: unwind the netdevice notifier if register_qdisc() fails Dudu Lu
  2026-10-21 15:58 ` netdev-bot+sinfo
@ 2026-10-23 10:59 ` Simon Horman
  2026-10-26 23:30 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 5+ messages in thread
From: Simon Horman @ 2026-10-23 10:59 UTC (permalink / raw)
  To: Dudu Lu; +Cc: vinicius.gomes, jhs, jiri, netdev

On Wed, Oct 21, 2026 at 11:54:17PM +0800, Dudu Lu wrote:
> taprio_module_init() registers taprio_device_notifier and then returns
> register_qdisc()'s error directly.  When register_qdisc() fails the
> notifier stays registered, but the loader's failure path frees the module
> image without ever calling the __exit function, so netdev_chain is left
> pointing at taprio_device_notifier.notifier_call -- a function pointer
> that lives in text that has just been freed.
> 
> register_qdisc() has two failure returns: -EEXIST (duplicate .id) and
> -EINVAL (malformed cl_ops).  taprio_class_ops satisfies every checked
> implication, so -EINVAL is unreachable and -EEXIST is the only reachable
> failure; it needs a pre-existing "taprio" entry in qdisc_base.  In-tree
> that is reachable only through bpf_qdisc_reg() (CONFIG_NET_SCH_BPF); a
> module calling the exported register_qdisc() reaches it as well.
> 
> Once the notifier is left dangling, the next netdevice event that walks
> netdev_chain calls through the stale pointer:
> 
>   BUG: KASAN: vmalloc-out-of-bounds in notifier_call_chain+0x650/0xb5c
>   Read of size 8 at addr ffff80001fc5ab08 by task ip/110
>    notifier_call_chain+0x650/0xb5c
>    raw_notifier_call_chain+0x34/0x64
>    call_netdevice_notifiers_info+0xa8/0x198
>    __dev_close_many+0xe0/0x800
>    ...
>   >ffff80001fc5ab00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
> 
> The shadow row is all f8 (KASAN_VMALLOC_INVALID): the read lands in
> vmalloc memory that was poisoned when the module image was freed, and the
> indirect call is unguarded because the only check, func_ptr_is_kernel_text(),
> is compiled out unless CONFIG_DEBUG_NOTIFIERS.
> 
> Mirror the sibling sch_cbs.c and act_mirred.c, which unwind the notifier
> on this failure path.
> 
> Fixes: 7b9eba7ba0c1 ("net/sched: taprio: fix picos_per_byte miscalculation")
> Assisted-by: LLM
> Signed-off-by: Dudu Lu <phx0fer@gmail.com>
> ---
> Tested base
> -----------
> Detected on Linux 7.3-rc4 (commit 93f51579e7df), arm64 QEMU guest.
> Re-checked against mainline f47d223627f8 (v7.3-341): the affected code
> is unchanged between the two, so the bug is still present there.
> Checked against linux-next next-20261021 (commit 9a482184d910): the
> affected code is unchanged there as well, so the bug is still present in
> linux-next too.
> 
> Reproducer status
> -----------------
> A reproducer was written and executed on an arm64 QEMU guest with
> CONFIG_NET_SCH_TAPRIO=m, KASAN_VMALLOC=y, CONFIG_MODULE_UNLOAD=y; it fires at the
> claimed sink.  The reproducer source is not posted here per
> Documentation/process/security-bugs.rst; it is available on request.
> 
> Triggering conditions
> ---------------------
> A pre-existing "taprio" entry in qdisc_base, so register_qdisc() returns
> -EEXIST (the only reachable failure).  In-tree this is reachable via
> bpf_qdisc_reg() (CONFIG_NET_SCH_BPF); the reproducer reaches it through the
> exported register_qdisc().  Then a NETDEV_UP event.
> 
> Notes
> -----
> Built and checkpatch-clean: this patch was applied on top of 7.3-rc4
> (commit 93f51579e7df) and a full arm64 kernel (defconfig) was built with
> it -- no new warnings or errors.  scripts/checkpatch.pl reports 0 errors,
> 0 warnings.

Reviewed-by: Simon Horman <horms@kernel.org>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net] net/sched: taprio: unwind the netdevice notifier if register_qdisc() fails
  2026-10-21 15:54 [PATCH net] net/sched: taprio: unwind the netdevice notifier if register_qdisc() fails Dudu Lu
  2026-10-21 15:58 ` netdev-bot+sinfo
  2026-10-23 10:59 ` Simon Horman
@ 2026-10-26 23:30 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-10-26 23:30 UTC (permalink / raw)
  To: Dudu Lu; +Cc: vinicius.gomes, jhs, jiri, netdev

Hello:

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

On Wed, 21 Oct 2026 23:54:17 +0800 you wrote:
> taprio_module_init() registers taprio_device_notifier and then returns
> register_qdisc()'s error directly.  When register_qdisc() fails the
> notifier stays registered, but the loader's failure path frees the module
> image without ever calling the __exit function, so netdev_chain is left
> pointing at taprio_device_notifier.notifier_call -- a function pointer
> that lives in text that has just been freed.
> 
> [...]

Here is the summary with links:
  - [net] net/sched: taprio: unwind the netdevice notifier if register_qdisc() fails
    https://git.kernel.org/netdev/net/c/c5234f89d7cb

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-26 23:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-21 15:54 [PATCH net] net/sched: taprio: unwind the netdevice notifier if register_qdisc() fails Dudu Lu
2026-10-21 15:58 ` netdev-bot+sinfo
2026-10-22  4:59   ` phx
2026-10-23 10:59 ` Simon Horman
2026-10-26 23:30 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox