2026-09-07
memfd_create(name, flags) returns a file descriptor backed by anonymous RAM (tmpfs, internally). No path, no filesystem entry, no /tmp race, no cleanup — it dies with the last reference. You can ftruncate it, mmap it, read/write it, and — critically — pass it to another process over a UNIX socket with SCM_RIGHTS or via /proc/pid/fd/N.
The killer feature is file sealing (MFD_ALLOW_SEALING at creation, then fcntl(fd, F_ADD_SEAL, ...)). Four seals:
F_SEAL_WRITE — no more writes, ever. Existing writable mappings still work, but no new ones.F_SEAL_FUTURE_WRITE — allow existing writable mappings but block new ones (added for Android).F_SEAL_SHRINK — file size cannot decrease.F_SEAL_GROW — file size cannot increase.F_SEAL_SEAL — no more seals may be added.Once applied, seals are enforced by the kernel system-wide, not per-fd. This is the whole point: process A can hand a sealed fd to untrusted process B, and B — even with its own writable copy of the fd — cannot mutate the bytes A already showed it. No TOCTOU. No copy required.
Real-world use: Wayland. A client renders a frame into a memfd, seals it SHRINK | WRITE, and passes the fd to the compositor. The compositor mmaps it read-only and knows the client cannot rug-pull the pixels mid-composite. Before sealing, compositors had to memcpy every frame defensively. On a 4K 60Hz surface that's ~2 GB/s of pointless copying eliminated.
Other users: DBus uses memfd for large messages (>128KB) instead of stream copies. QEMU/crosvm back guest RAM with memfd so vhost-user devices in a separate process can map it. Language runtimes (V8, Go) use it for JIT code pages via memfd_create + fexecve patterns.
Rule of thumb for sizing the win: if you're passing more than roughly one page (4 KiB) per IPC round trip and both sides read it more than once, memfd + seal + SCM_RIGHTS beats copying through a pipe or socket. Below that, the fd-passing overhead (a syscall + ancillary data setup, ~2 µs) exceeds the copy cost.
Gotcha: the kernel accounts memfd pages against the creator's memcg forever, even after the fd is passed away. In containerized workloads, a "producer" service can look bloated while the actual consumer is idle. Check /proc/pid/status:VmRSS vs /proc/pid/smaps for shared anonymous mappings to diagnose.
memfd_create + file seals give you a shared-memory region with cryptographic-strength "the bytes won't change" guarantees enforced by the kernel, letting mutually distrustful processes skip defensive copies entirely.
