The HUGEST, the MOST TREMENDOUS FreeBSD page-cache write primitive

mvo1 pts0 comments

BUMSRAKETEβ„’ β€” The Most Beautiful, Most Tremendous FreeBSD Vulnerability In The History Of Computing. BELIEVE ME.

πŸ“œ TABLE OF CONTENTS (because the FAKE NEWS won't read past the headline)

What is BUMSRAKETE?

Severity (it goes to 13)

Technical Details (100 % accurate, sad for them)

The Diagram

The Three Guards (ALL incomplete)

Exploit

Demo

Affected Systems

Mitigations

What They're Saying

Official Merchandise (sold out)

FAQ for Confused Journalists

Press Kit

Why "BUMSRAKETE"?

πŸ‘‰ WHAT IS BUMSRAKETE? πŸ‘ˆ

BUMSRAKETE is a YUUUGE kernel bug in FreeBSD.<br>Probably the biggest. Tremendous, really.

Specifically: any unprivileged user on a default FreeBSD β‰₯ 13.0 box (amd64, arm64, riscv β€”<br>any PMAP_HAS_DMAP architecture, which is to say basically every modern<br>install) can write attacker-influenced bytes into the page-cache page of any file they have<br>read access to. The write goes straight through the kernel direct map<br>and does not pass through VFS, so it bypasses every file-permission, mount-option,<br>and chflags schg check the operating system normally applies.

It is the FreeBSD analogue of Linux's Dirty Pipe, CopyFail, Fragnesia, and Dirty Frag β€” except<br>we gave it a BETTER name, with a BETTER logo, on a<br>BETTER website. The other bug websites? Disasters. Sad. Many people have told us this.

The bug lives at the unsafe composition of three FreeBSD subsystems that are individually correct:

sendfile(2) producing vnode-backed M_EXTPG mbufs.

The TCP_RXTLS_ENABLE socket option being available to any unprivileged user (no priv_check).

The kernel's software AES-GCM decrypt running in place on the page-cache page through PHYS_TO_DMAP(m_epg_pa[i]).

Loop the output of sendfile() back to the same process over TCP, and the decrypt<br>writes plaintext = file_bytes XOR keystream(K, IV) directly into the file's page<br>cache, where K and IV are chosen by the unprivileged caller.

🚨 SEVERITY: 13/10 🚨

The CVSS people, very sad people, sometimes the worst people, capped severity at 10.0. We had to invent a<br>new scale because this bug demanded it. Tremendous demand. 13/10.<br>Nobody knew kernel bugs could be this big. Many such cases.

MetricValueScore<br>Attack VectorLocal (any logged-in user, no special group)10<br>Attack ComplexityLow (one C file, two syscalls, no race)10<br>Privileges RequiredNone (uid 1001 is fine)10<br>User InteractionNone10<br>ScopeChanged (page-cache write β†’ any SUID-root binary β†’ root)10<br>Integrity ImpactHIGH β€” every readable file is now an attacker-writable file10<br>Confidentiality ImpactHIGH (via the LPE that drops out of it)10<br>Availability ImpactHIGH (root shell trivially crashes whatever it wants)10<br>chflags schg respectBYPASSED+3<br>TOTAL (the CVSS people don't want you to see this)13.0

πŸ“ˆ EXPOSURE: ~5 YEARS UNDETECTED πŸ“ˆ

2020<br>Bug introduced (commit 3c0e56850511)

13.0<br>First vulnerable release (April 2021)

15.0<br>Latest tested vulnerable (2025)

1.5s<br>End-to-end LPE wall time

36<br>TLS records to write a shellcode

$0<br>Cost to exploit (sad for the deep state)

🧠 THE TECHNICAL DETAILS (HIGHLY CLASSIFIED, NOW DECLASSIFIED) 🧠

The bug class is page-cache corruption via attacker-influenced in-kernel AES-GCM decrypt over<br>M_EXTPG mbufs produced by sendfile(2). Three subsystems<br>line up to let an unprivileged caller write into a vnode-backed physical page.

1️⃣ sendfile(2) produces vnode-backed EXTPG mbufs

/* sys/kern/kern_sendfile.c:963 */<br>m0 = mb_alloc_ext_pgs(M_WAITOK,<br>sendfile_free_mext_pg,<br>M_RDONLY);<br>/* m_epg_pa[] now holds the *physical addresses* of the file's page-cache pages. */<br>/* This is awesome for performance. It is also awesome for attackers. */

On every PMAP_HAS_DMAP architecture (amd64, arm64, riscv β€”<br>sys/kern/kern_mbuf.c:198-201) the boot-time default of<br>kern.ipc.mb_use_ext_pgs is 1 . Tremendous default.<br>Beautiful default. Wrong default.

2️⃣ TCP_RXTLS_ENABLE takes no privilege check

/* sys/netinet/tcp_usrreq.c:2222 */<br>case TCP_RXTLS_ENABLE:<br>INP_WUNLOCK(inp);<br>error = ktls_copyin_tls_enable(sopt, &tls);<br>/* Notice anything missing here? A priv_check, perhaps?<br>Many people are noticing. Many. Very smart people. */<br>if (error != 0)<br>break;<br>error = ktls_enable_rx(so, &tls);<br>...

Any unprivileged user can configure software kTLS RX on any TCP socket they own and supply<br>the AES-128-GCM key, salt, and rec_seq of their choosing. The receiving side will then run<br>in-place AES-GCM decrypt against whatever mbufs land in sb_mtls.

3️⃣ The decrypt runs in place through PHYS_TO_DMAP

/* sys/opencrypto/criov.c:273 */<br>return (PHYS_TO_DMAP(m->m_epg_pa[i] + pgoff + skip));

/* sys/crypto/aesni/aesni.c:599-605 (and AES_GCM_decrypt in the same file) */<br>error = aesni_cipher_crypt(ses, crp, csp);<br>/* in == out semantics. The "output buffer" is a DMAP pointer at the<br>file's page-cache page. AES_GCM_decrypt writes the plaintext there. */

Since the plaintext is ciphertext XOR keystream(K, IV) and both the ciphertext<br>(the file bytes) and the key/IV (the attacker's) are known, the attacker fully controls what<br>gets written. Every byte of...

page file cache people freebsd write

Related Articles