-

CVE-2026-98547

af_packet: fix integer overflow in prb_calc_retire_blk_tmo()

In the Linux kernel, the following vulnerability has been resolved:

af_packet: fix integer overflow in prb_calc_retire_blk_tmo()

prb_calc_retire_blk_tmo() computes in 32-bit int arithmetic:

        mbits = (blk_size_in_bytes * 8) / (1024 * 1024);

If I'm reading the validation right, tp_block_size is user
controlled and packet_set_ring() only rejects values that are <= 0
as int or not page aligned, so a 256MiB block goes right through
(and alloc_one_pg_vec_page() even has a vzalloc fallback for it).
0x10000000 * 8 wraps to INT_MIN, and on a NIC reporting 1 Gbps
(div == 1) the function ends up returning -2047.

The condition is actually (8 * size) mod 2^32 >= 2^31 && div == 1,
so the trigger set is [256,512), [768,1024), [1280,1536) and
[1792,2048) MiB. Other sizes wrap to non-negative values and faster
links divide the unsigned value back below 2^31, which is why this
doesn't blow up for everyone.

What makes it fatal is what happens next in init_prb_bdqc():

        p1->interval_ktime = ms_to_ktime(prb_calc_retire_blk_tmo(...));
        hrtimer_start(&p1->retire_blk_timer, p1->interval_ktime,
                      HRTIMER_MODE_REL_SOFT);

A negative relative timeout expires immediately. The callback
unconditionally returns HRTIMER_RESTART, and hrtimer_forward() turns
the negative interval into hrtimer_resolution:

        if (interval < hrtimer_resolution)
                interval = hrtimer_resolution;

So the SOFT timer re-fires at the maximum rate forever, holding
sk_receive_queue.lock each pass. One CPU spins in softirq until the
socket is closed. Repeat with more rings and the machine is gone.

The overflow itself is ancient - it was introduced together with
TPACKET_V3 in f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer
implementation."). Its effect prior to f7460d2989fa ("net:
af_packet: Use hrtimer to do the retire operation", v6.18) was not
as clear-cut, though: the return value was stored into an unsigned
short retire_blk_tov, so a negative result was truncated, and a
0-jiffy delay loop could be programmed as well. Neither is nearly
as detrimental as the immediate maximum-rate spin the hrtimer
conversion turned it into.

(Unrelated to CVE-2019-20812 - that one was the ethtool failure path
returning 0, which now returns DEFAULT_PRB_RETIRE_TOV.)

Reproducer, needs CAP_NET_RAW (a --network host container has it by
default) and a 1 Gbps NIC (QEMU e1000 works):

        int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
        bind(fd, ...);
        int v = TPACKET_V3;
        setsockopt(fd, SOL_PACKET, PACKET_VERSION, &v, sizeof(v));
        struct tpacket_req3 req = {
                .tp_block_size = 0x10000000,
                .tp_block_nr = 1,
                .tp_frame_size = 2048,
                .tp_frame_nr = 0x10000000 / 2048,
                .tp_retire_blk_tov = 0,
        };
        setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req));

Compute in 64 bits instead. The operands are already bounded by the
existing validation, so nothing else changes. If you'd prefer a
different fix, just say so and I'll respin.
Daten sind bereitgestellt durch das CVE Programm von einer CVE Numbering Authority (CNA) (Unstrukturiert).
HerstellerLinux
≫
Produkt Linux
Default Statusunaffected
Version f6fb8f100b807378fda19e83e5ac6828b638603a
Version < 02afd75649a4e001031ed82153a5c39312ec0737
Status affected
Version f6fb8f100b807378fda19e83e5ac6828b638603a
Version < eb5b3838b9200dac04bfe33483db0ee8287456fb
Status affected
Version f6fb8f100b807378fda19e83e5ac6828b638603a
Version < 297acc571d5813db76b147c745b91031d5f9c960
Status affected
Version f6fb8f100b807378fda19e83e5ac6828b638603a
Version < be1aacff399d519cc48d6b34354a54dd79041140
Status affected
Version f6fb8f100b807378fda19e83e5ac6828b638603a
Version < b2bcc6a254d6f27823a56787668ae4ee8cdb6e71
Status affected
Version f6fb8f100b807378fda19e83e5ac6828b638603a
Version < 6279211e7d2456ecd195d236c9ee5e5c6fa5a17a
Status affected
Version f6fb8f100b807378fda19e83e5ac6828b638603a
Version < 218a944b9e035d4b47d59c69af6ca13319da15fb
Status affected
Version f6fb8f100b807378fda19e83e5ac6828b638603a
Version < 56d82862a0a243ac14ba11b6d7b57ddc2d064b95
Status affected
HerstellerLinux
≫
Produkt Linux
Default Statusaffected
Version 3.2
Status affected
Version 0
Version < 3.2
Status unaffected
Version <= 5.10.*
Version 5.10.271
Status unaffected
Version <= 5.15.*
Version 5.15.222
Status unaffected
Version <= 6.1.*
Version 6.1.189
Status unaffected
Version <= 6.6.*
Version 6.6.158
Status unaffected
Version <= 6.12.*
Version 6.12.112
Status unaffected
Version <= 6.18.*
Version 6.18.55
Status unaffected
Version <= 7.2.*
Version 7.2.9
Status unaffected
Version <= *
Version 7.3
Status unaffected
VulnDex Vulnerability Enrichment
Diese Information steht angemeldeten Benutzern zur Verfügung. Login Login
Zu dieser CVE wurde keine Warnung gefunden.
EPSS Metriken
Typ Quelle Score Percentile
EPSS FIRST.org 0.21% 0.106
CVSS Metriken
Quelle Base Score Exploit Score Impact Score Vector String
Es wurden noch keine Informationen zu CWE veröffentlicht.
https://git.kernel.org/stable/c/02afd75649a4e001031ed82153a5c39312ec0737
https://git.kernel.org/stable/c/eb5b3838b9200dac04bfe33483db0ee8287456fb
https://git.kernel.org/stable/c/297acc571d5813db76b147c745b91031d5f9c960
https://git.kernel.org/stable/c/be1aacff399d519cc48d6b34354a54dd79041140
https://git.kernel.org/stable/c/b2bcc6a254d6f27823a56787668ae4ee8cdb6e71
https://git.kernel.org/stable/c/6279211e7d2456ecd195d236c9ee5e5c6fa5a17a
https://git.kernel.org/stable/c/218a944b9e035d4b47d59c69af6ca13319da15fb
https://git.kernel.org/stable/c/56d82862a0a243ac14ba11b6d7b57ddc2d064b95