diff mbox series

[net-n] net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT

Message ID 20241024165547.418570-1-jhs@mojatatu.com (mailing list archive)
State Accepted
Commit 2e95c4384438adeaa772caa560244b1a2efef816
Delegated to: Netdev Maintainers
Headers show
Series [net-n] net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 5 this patch: 5
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 1 maintainers not CCed: horms@kernel.org
netdev/build_clang success Errors and warnings before: 3 this patch: 3
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
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: 4 this patch: 4
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-10-26--21-00 (tests: 777)

Commit Message

Jamal Hadi Salim Oct. 24, 2024, 4:55 p.m. UTC
From: Pedro Tammela <pctammela@mojatatu.com>

In qdisc_tree_reduce_backlog, Qdiscs with major handle ffff: are assumed
to be either root or ingress. This assumption is bogus since it's valid
to create egress qdiscs with major handle ffff:
Budimir Markovic found that for qdiscs like DRR that maintain an active
class list, it will cause a UAF with a dangling class pointer.

In 066a3b5b2346, the concern was to avoid iterating over the ingress
qdisc since its parent is itself. The proper fix is to stop when parent
TC_H_ROOT is reached because the only way to retrieve ingress is when a
hierarchy which does not contain a ffff: major handle call into
qdisc_lookup with TC_H_MAJ(TC_H_ROOT).

In the scenario where major ffff: is an egress qdisc in any of the tree
levels, the updates will also propagate to TC_H_ROOT, which then the
iteration must stop.

Fixes: 066a3b5b2346 ("[NET_SCHED] sch_api: fix qdisc_tree_decrease_qlen() loop")
Reported-by: Budimir Markovic <markovicbudimir@gmail.com>
Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>

 net/sched/sch_api.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Simon Horman Oct. 25, 2024, 8:58 a.m. UTC | #1
On Thu, Oct 24, 2024 at 12:55:47PM -0400, Jamal Hadi Salim wrote:
> From: Pedro Tammela <pctammela@mojatatu.com>
> 
> In qdisc_tree_reduce_backlog, Qdiscs with major handle ffff: are assumed
> to be either root or ingress. This assumption is bogus since it's valid
> to create egress qdiscs with major handle ffff:
> Budimir Markovic found that for qdiscs like DRR that maintain an active
> class list, it will cause a UAF with a dangling class pointer.
> 
> In 066a3b5b2346, the concern was to avoid iterating over the ingress
> qdisc since its parent is itself. The proper fix is to stop when parent
> TC_H_ROOT is reached because the only way to retrieve ingress is when a
> hierarchy which does not contain a ffff: major handle call into
> qdisc_lookup with TC_H_MAJ(TC_H_ROOT).
> 
> In the scenario where major ffff: is an egress qdisc in any of the tree
> levels, the updates will also propagate to TC_H_ROOT, which then the
> iteration must stop.
> 
> Fixes: 066a3b5b2346 ("[NET_SCHED] sch_api: fix qdisc_tree_decrease_qlen() loop")
> Reported-by: Budimir Markovic <markovicbudimir@gmail.com>
> Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
> Tested-by: Victor Nogueira <victor@mojatatu.com>
> Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>

Reviewed-by: Simon Horman <horms@kernel.org>
Cong Wang Oct. 26, 2024, 4:47 p.m. UTC | #2
On Thu, Oct 24, 2024 at 12:55:47PM -0400, Jamal Hadi Salim wrote:
> From: Pedro Tammela <pctammela@mojatatu.com>
> 
> In qdisc_tree_reduce_backlog, Qdiscs with major handle ffff: are assumed
> to be either root or ingress. This assumption is bogus since it's valid
> to create egress qdiscs with major handle ffff:
> Budimir Markovic found that for qdiscs like DRR that maintain an active
> class list, it will cause a UAF with a dangling class pointer.
> 
> In 066a3b5b2346, the concern was to avoid iterating over the ingress
> qdisc since its parent is itself. The proper fix is to stop when parent
> TC_H_ROOT is reached because the only way to retrieve ingress is when a
> hierarchy which does not contain a ffff: major handle call into
> qdisc_lookup with TC_H_MAJ(TC_H_ROOT).
> 
> In the scenario where major ffff: is an egress qdisc in any of the tree
> levels, the updates will also propagate to TC_H_ROOT, which then the
> iteration must stop.
> 
> Fixes: 066a3b5b2346 ("[NET_SCHED] sch_api: fix qdisc_tree_decrease_qlen() loop")
> Reported-by: Budimir Markovic <markovicbudimir@gmail.com>
> Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
> Tested-by: Victor Nogueira <victor@mojatatu.com>
> Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
> 
>  net/sched/sch_api.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Can we also add a selftest since it is reproducible?

I am not saying you have to put it together with this patch, a separate patch is
certainly okay.

Thanks.
Pedro Tammela Oct. 28, 2024, 2:36 p.m. UTC | #3
On 26/10/2024 13:47, Cong Wang wrote:
> On Thu, Oct 24, 2024 at 12:55:47PM -0400, Jamal Hadi Salim wrote:
>> From: Pedro Tammela <pctammela@mojatatu.com>
>>
>> In qdisc_tree_reduce_backlog, Qdiscs with major handle ffff: are assumed
>> to be either root or ingress. This assumption is bogus since it's valid
>> to create egress qdiscs with major handle ffff:
>> Budimir Markovic found that for qdiscs like DRR that maintain an active
>> class list, it will cause a UAF with a dangling class pointer.
>>
>> In 066a3b5b2346, the concern was to avoid iterating over the ingress
>> qdisc since its parent is itself. The proper fix is to stop when parent
>> TC_H_ROOT is reached because the only way to retrieve ingress is when a
>> hierarchy which does not contain a ffff: major handle call into
>> qdisc_lookup with TC_H_MAJ(TC_H_ROOT).
>>
>> In the scenario where major ffff: is an egress qdisc in any of the tree
>> levels, the updates will also propagate to TC_H_ROOT, which then the
>> iteration must stop.
>>
>> Fixes: 066a3b5b2346 ("[NET_SCHED] sch_api: fix qdisc_tree_decrease_qlen() loop")
>> Reported-by: Budimir Markovic <markovicbudimir@gmail.com>
>> Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
>> Tested-by: Victor Nogueira <victor@mojatatu.com>
>> Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
>> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
>>
>>   net/sched/sch_api.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
> 
> Can we also add a selftest since it is reproducible?

Yep, we are just waiting for it to be in net-next so we don't crash 
downstream CIs
Jakub Kicinski Oct. 29, 2024, 4 p.m. UTC | #4
On Mon, 28 Oct 2024 11:36:00 -0300 Pedro Tammela wrote:
> > Can we also add a selftest since it is reproducible?  
> 
> Yep, we are just waiting for it to be in net-next so we don't crash 
> downstream CIs

Can you say more? It's more common to include the test in the same
series as the fix. Which CI would break?
patchwork-bot+netdevbpf@kernel.org Oct. 29, 2024, 6:40 p.m. UTC | #5
Hello:

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

On Thu, 24 Oct 2024 12:55:47 -0400 you wrote:
> From: Pedro Tammela <pctammela@mojatatu.com>
> 
> In qdisc_tree_reduce_backlog, Qdiscs with major handle ffff: are assumed
> to be either root or ingress. This assumption is bogus since it's valid
> to create egress qdiscs with major handle ffff:
> Budimir Markovic found that for qdiscs like DRR that maintain an active
> class list, it will cause a UAF with a dangling class pointer.
> 
> [...]

Here is the summary with links:
  - [net-n] net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT
    https://git.kernel.org/netdev/net/c/2e95c4384438

You are awesome, thank you!
diff mbox series

Patch

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 2eefa4783879..a1d27bc039a3 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -791,7 +791,7 @@  void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len)
 	drops = max_t(int, n, 0);
 	rcu_read_lock();
 	while ((parentid = sch->parent)) {
-		if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS))
+		if (parentid == TC_H_ROOT)
 			break;
 
 		if (sch->flags & TCQ_F_NOPARENT)