{"id":41019,"date":"2026-10-19T00:31:50","date_gmt":"2026-10-18T16:31:50","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98547"},"modified":"2026-10-19T00:31:50","modified_gmt":"2026-10-18T16:31:50","slug":"cve-2026-98547","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98547","title":{"rendered":"CVE-2026-98547 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\naf_packet: fix intege"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>af_packet: fix integer overflow in prb_calc_retire_blk_tmo()<\/p>\n<p>prb_calc_retire_blk_tmo() computes in 32-bit int arithmetic:<\/p>\n<p>        mbits = (blk_size_in_bytes * 8) \/ (1024 * 1024);<\/p>\n<p>If I&#8217;m reading the validation right, tp_block_size is user<br \/>\ncontrolled and packet_set_ring() only rejects values that are = 2^31 &amp;&amp; div == 1,<br \/>\nso the trigger set is [256,512), [768,1024), [1280,1536) and<br \/>\n[1792,2048) MiB. Other sizes wrap to non-negative values and faster<br \/>\nlinks divide the unsigned value back below 2^31, which is why this<br \/>\ndoesn&#8217;t blow up for everyone.<\/p>\n<p>What makes it fatal is what happens next in init_prb_bdqc():<\/p>\n<p>        p1-&gt;interval_ktime = ms_to_ktime(prb_calc_retire_blk_tmo(&#8230;));<br \/>\n        hrtimer_start(&amp;p1-&gt;retire_blk_timer, p1-&gt;interval_ktime,<br \/>\n                      HRTIMER_MODE_REL_SOFT);<\/p>\n<p>A negative relative timeout expires immediately. The callback<br \/>\nunconditionally returns HRTIMER_RESTART, and hrtimer_forward() turns<br \/>\nthe negative interval into hrtimer_resolution:<\/p>\n<p>        if (interval &lt; hrtimer_resolution)<br \/>\n                interval = hrtimer_resolution;<\/p>\n<p>So the SOFT timer re-fires at the maximum rate forever, holding<br \/>\nsk_receive_queue.lock each pass. One CPU spins in softirq until the<br \/>\nsocket is closed. Repeat with more rings and the machine is gone.<\/p>\n<p>The overflow itself is ancient &#8211; it was introduced together with<br \/>\nTPACKET_V3 in f6fb8f100b80 (&quot;af-packet: TPACKET_V3 flexible buffer<br \/>\nimplementation.&quot;). Its effect prior to f7460d2989fa (&quot;net:<br \/>\naf_packet: Use hrtimer to do the retire operation&quot;, v6.18) was not<br \/>\nas clear-cut, though: the return value was stored into an unsigned<br \/>\nshort retire_blk_tov, so a negative result was truncated, and a<br \/>\n0-jiffy delay loop could be programmed as well. Neither is nearly<br \/>\nas detrimental as the immediate maximum-rate spin the hrtimer<br \/>\nconversion turned it into.<\/p>\n<p>(Unrelated to CVE-2019-20812 &#8211; that one was the ethtool failure path<br \/>\nreturning 0, which now returns DEFAULT_PRB_RETIRE_TOV.)<\/p>\n<p>Reproducer, needs CAP_NET_RAW (a &#8211;network host container has it by<br \/>\ndefault) and a 1 Gbps NIC (QEMU e1000 works):<\/p>\n<p>        int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));<br \/>\n        bind(fd, &#8230;);<br \/>\n        int v = TPACKET_V3;<br \/>\n        setsockopt(fd, SOL_PACKET, PACKET_VERSION, &amp;v, sizeof(v));<br \/>\n        struct tpacket_req3 req = {<br \/>\n                .tp_block_size = 0x10000000,<br \/>\n                .tp_block_nr = 1,<br \/>\n                .tp_frame_size = 2048,<br \/>\n                .tp_frame_nr = 0x10000000 \/ 2048,<br \/>\n                .tp_retire_blk_tov = 0,<br \/>\n        };<br \/>\n        setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &amp;req, sizeof(req));<\/p>\n<p>Compute in 64 bits instead. The operands are already bounded by the<br \/>\nexisting validation, so nothing else changes. If you&#039;d prefer a<br \/>\ndifferent fix, just say so and I&#039;ll respin.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>af_packet: fix integer overflow in prb_calc_retire_blk_tmo()<\/p>\n<p>prb_calc_retire_blk_tmo() computes in 32-bit int arithmetic:<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-41019","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/41019","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln"}],"about":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/types\/vuln"}],"wp:attachment":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=41019"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=41019"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=41019"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}