CVE-2025-21702

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
18/02/2025
Last modified:
13/03/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> pfifo_tail_enqueue: Drop new packet when sch-&gt;limit == 0<br /> <br /> Expected behaviour:<br /> In case we reach scheduler&amp;#39;s limit, pfifo_tail_enqueue() will drop a<br /> packet in scheduler&amp;#39;s queue and decrease scheduler&amp;#39;s qlen by one.<br /> Then, pfifo_tail_enqueue() enqueue new packet and increase<br /> scheduler&amp;#39;s qlen by one. Finally, pfifo_tail_enqueue() return<br /> `NET_XMIT_CN` status code.<br /> <br /> Weird behaviour:<br /> In case we set `sch-&gt;limit == 0` and trigger pfifo_tail_enqueue() on a<br /> scheduler that has no packet, the &amp;#39;drop a packet&amp;#39; step will do nothing.<br /> This means the scheduler&amp;#39;s qlen still has value equal 0.<br /> Then, we continue to enqueue new packet and increase scheduler&amp;#39;s qlen by<br /> one. In summary, we can leverage pfifo_tail_enqueue() to increase qlen by<br /> one and return `NET_XMIT_CN` status code.<br /> <br /> The problem is:<br /> Let&amp;#39;s say we have two qdiscs: Qdisc_A and Qdisc_B.<br /> - Qdisc_A&amp;#39;s type must have &amp;#39;-&gt;graft()&amp;#39; function to create parent/child relationship.<br /> Let&amp;#39;s say Qdisc_A&amp;#39;s type is `hfsc`. Enqueue packet to this qdisc will trigger `hfsc_enqueue`.<br /> - Qdisc_B&amp;#39;s type is pfifo_head_drop. Enqueue packet to this qdisc will trigger `pfifo_tail_enqueue`.<br /> - Qdisc_B is configured to have `sch-&gt;limit == 0`.<br /> - Qdisc_A is configured to route the enqueued&amp;#39;s packet to Qdisc_B.<br /> <br /> Enqueue packet through Qdisc_A will lead to:<br /> - hfsc_enqueue(Qdisc_A) -&gt; pfifo_tail_enqueue(Qdisc_B)<br /> - Qdisc_B-&gt;q.qlen += 1<br /> - pfifo_tail_enqueue() return `NET_XMIT_CN`<br /> - hfsc_enqueue() check for `NET_XMIT_SUCCESS` and see `NET_XMIT_CN` =&gt; hfsc_enqueue() don&amp;#39;t increase qlen of Qdisc_A.<br /> <br /> The whole process lead to a situation where Qdisc_A-&gt;q.qlen == 0 and Qdisc_B-&gt;q.qlen == 1.<br /> Replace &amp;#39;hfsc&amp;#39; with other type (for example: &amp;#39;drr&amp;#39;) still lead to the same problem.<br /> This violate the design where parent&amp;#39;s qlen should equal to the sum of its childrens&amp;#39;qlen.<br /> <br /> Bug impact: This issue can be used for user-&gt;kernel privilege escalation when it is reachable.

Impact