Patch "net/sched: sch_api: fix xa_insert() error path in tcf_block_get_ext()" has been added to the 6.11-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net/sched: sch_api: fix xa_insert() error path in tcf_block_get_ext()

to the 6.11-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-sched-sch_api-fix-xa_insert-error-path-in-tcf_bl.patch
and it can be found in the queue-6.11 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 793fcd719a656c0db67b988adf9d42911ff40b26
Author: Vladimir Oltean <vladimir.oltean@xxxxxxx>
Date:   Wed Oct 23 13:05:41 2024 +0300

    net/sched: sch_api: fix xa_insert() error path in tcf_block_get_ext()
    
    [ Upstream commit a13e690191eafc154b3f60afe9ce35aa9b9128b4 ]
    
    This command:
    
    $ tc qdisc replace dev eth0 ingress_block 1 egress_block 1 clsact
    Error: block dev insert failed: -EBUSY.
    
    fails because user space requests the same block index to be set for
    both ingress and egress.
    
    [ side note, I don't think it even failed prior to commit 913b47d3424e
      ("net/sched: Introduce tc block netdev tracking infra"), because this
      is a command from an old set of notes of mine which used to work, but
      alas, I did not scientifically bisect this ]
    
    The problem is not that it fails, but rather, that the second time
    around, it fails differently (and irrecoverably):
    
    $ tc qdisc replace dev eth0 ingress_block 1 egress_block 1 clsact
    Error: dsa_core: Flow block cb is busy.
    
    [ another note: the extack is added by me for illustration purposes.
      the context of the problem is that clsact_init() obtains the same
      &q->ingress_block pointer as &q->egress_block, and since we call
      tcf_block_get_ext() on both of them, "dev" will be added to the
      block->ports xarray twice, thus failing the operation: once through
      the ingress block pointer, and once again through the egress block
      pointer. the problem itself is that when xa_insert() fails, we have
      emitted a FLOW_BLOCK_BIND command through ndo_setup_tc(), but the
      offload never sees a corresponding FLOW_BLOCK_UNBIND. ]
    
    Even correcting the bad user input, we still cannot recover:
    
    $ tc qdisc replace dev swp3 ingress_block 1 egress_block 2 clsact
    Error: dsa_core: Flow block cb is busy.
    
    Basically the only way to recover is to reboot the system, or unbind and
    rebind the net device driver.
    
    To fix the bug, we need to fill the correct error teardown path which
    was missed during code movement, and call tcf_block_offload_unbind()
    when xa_insert() fails.
    
    [ last note, fundamentally I blame the label naming convention in
      tcf_block_get_ext() for the bug. The labels should be named after what
      they do, not after the error path that jumps to them. This way, it is
      obviously wrong that two labels pointing to the same code mean
      something is wrong, and checking the code correctness at the goto site
      is also easier ]
    
    Fixes: 94e2557d086a ("net: sched: move block device tracking into tcf_block_get/put_ext()")
    Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
    Reviewed-by: Simon Horman <horms@xxxxxxxxxx>
    Acked-by: Jamal Hadi Salim <jhs@xxxxxxxxxxxx>
    Link: https://patch.msgid.link/20241023100541.974362-1-vladimir.oltean@xxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 17d97bbe890fd..bbc778c233c89 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1518,6 +1518,7 @@ int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
 	return 0;
 
 err_dev_insert:
+	tcf_block_offload_unbind(block, q, ei);
 err_block_offload_bind:
 	tcf_chain0_head_change_cb_del(block, ei);
 err_chain0_head_change_cb_add:




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux