CVE-2024-53044
Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
19/11/2024
Last modified:
27/11/2024
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
net/sched: sch_api: fix xa_insert() error path in tcf_block_get_ext()<br />
<br />
This command:<br />
<br />
$ tc qdisc replace dev eth0 ingress_block 1 egress_block 1 clsact<br />
Error: block dev insert failed: -EBUSY.<br />
<br />
fails because user space requests the same block index to be set for<br />
both ingress and egress.<br />
<br />
[ side note, I don&#39;t think it even failed prior to commit 913b47d3424e<br />
("net/sched: Introduce tc block netdev tracking infra"), because this<br />
is a command from an old set of notes of mine which used to work, but<br />
alas, I did not scientifically bisect this ]<br />
<br />
The problem is not that it fails, but rather, that the second time<br />
around, it fails differently (and irrecoverably):<br />
<br />
$ tc qdisc replace dev eth0 ingress_block 1 egress_block 1 clsact<br />
Error: dsa_core: Flow block cb is busy.<br />
<br />
[ another note: the extack is added by me for illustration purposes.<br />
the context of the problem is that clsact_init() obtains the same<br />
&q->ingress_block pointer as &q->egress_block, and since we call<br />
tcf_block_get_ext() on both of them, "dev" will be added to the<br />
block->ports xarray twice, thus failing the operation: once through<br />
the ingress block pointer, and once again through the egress block<br />
pointer. the problem itself is that when xa_insert() fails, we have<br />
emitted a FLOW_BLOCK_BIND command through ndo_setup_tc(), but the<br />
offload never sees a corresponding FLOW_BLOCK_UNBIND. ]<br />
<br />
Even correcting the bad user input, we still cannot recover:<br />
<br />
$ tc qdisc replace dev swp3 ingress_block 1 egress_block 2 clsact<br />
Error: dsa_core: Flow block cb is busy.<br />
<br />
Basically the only way to recover is to reboot the system, or unbind and<br />
rebind the net device driver.<br />
<br />
To fix the bug, we need to fill the correct error teardown path which<br />
was missed during code movement, and call tcf_block_offload_unbind()<br />
when xa_insert() fails.<br />
<br />
[ last note, fundamentally I blame the label naming convention in<br />
tcf_block_get_ext() for the bug. The labels should be named after what<br />
they do, not after the error path that jumps to them. This way, it is<br />
obviously wrong that two labels pointing to the same code mean<br />
something is wrong, and checking the code correctness at the goto site<br />
is also easier ]
Impact
Base Score 3.x
5.50
Severity 3.x
MEDIUM
Vulnerable products and versions
CPE | From | Up to |
---|---|---|
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.8 (including) | 6.11.7 (excluding) |
cpe:2.3:o:linux:linux_kernel:6.12:rc1:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.12:rc2:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.12:rc3:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.12:rc4:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.12:rc5:*:*:*:*:*:* |
To consult the complete list of CPE names with products and versions, see this page