{"slug": "vdr-an-attempt-at-a-coredump-handler-secure-by-design-requesting-review", "title": "Vdr – an attempt at a coredump handler secure by design (requesting review)", "summary": "Vdr, a secure-by-design Linux core dump handler written in Rust, is seeking review, claiming to eliminate the CVE-2022-4415 class of vulnerabilities by using 0600 root-only file permissions and avoiding ACL code. The handler, which supports pipe and socket modes, also protects against CVE-2025-4598 by not reading auxv and uses kernel-tracked sensitivity flags on Linux 6.16 or later. The project was developed with AI assistance and is designed to handle potentially malicious core dump data from crashed processes.", "body_md": "**vdr** stands for *Voyage Data Recorder* — the maritime equivalent of a\nflight data recorder. Ships record what happens during a voyage; vdr records\nwhat happens when a process crashes.\n\nA modern, secure Linux core dump handler in Rust. Supports both pipe and socket modes.\n\nThis project was developed with AI assistance. The security claims below are written so that they can be verified independently of how the code was produced.\n\nvdr runs as root, invoked by the kernel to capture core dumps — memory\nsnapshots that may contain `/etc/shadow` hashes, API keys, private keys,\nand other credentials from crashed processes.\n\nThe primary attacker is a **local unprivileged user** who can:\n\n- Crash arbitrary programs, including SUID binaries\n- Control `argv[0]` and environment variables\n- Fork processes and manipulate PID namespaces\n- Trigger crashes in remote daemons (nginx, postgres workers), effectively gaining the same capability through crashed processes\n\nThe crashing process's memory image and `/proc/pid/*` snapshot are treated\nas potentially malicious input.\n\n**Access control**\n\n- **No ACL attack surface** — Core files are 0600 root-only via`O_CREAT|O_EXCL` . No`setfacl` , no`libacl` . The`fs.suid_dumpable=2` sysctl drop-in ships with vdrd to enable SUID/SGID core dumps; this\nis safe because 0600 root-only access control eliminates the\nCVE-2022-4415 class entirely (the CVE's mechanism was an ACL entry\ngranting read access to the real UID — impossible without ACL code,\nand the 0600 root-only default covers other leak paths too).\n\n**Hot path safety**\n\n- \n**No DWARF in the hot path** — vdr never parses DWARF in the recording\npath. A separate cold-path analysis tool (`vdr-analyze` ) is planned but\nnot yet implemented. gimli's maintainer explicitly states it is not a\nsecurity boundary[gimli PR #889](https://github.com/gimli-rs/gimli/pull/889) ;\nlibdwarf's design goal includes handling corrupted input\n([libdwarf README](https://github.com/davea42/libdwarf-code/blob/main/README.md) ),\nbut its own vulnerability database lists 239 entries as of July 2026\n([dwarfbug.html](https://www.prevanders.net/dwarfbug.html) , latest:\nDW202605-008). Neither should be relied upon as a security boundary\nin the recording path.\n- \n**Streaming, bounded memory** — Core data streams through`io::copy` into a zstd encoder to disk, never fully loaded into RAM. Per-core\nlimit: 2 GB. Executable size limit for build ID extraction: 64 MB.\nThe systemd unit enforces`MemoryMax=256M` ,`TasksMax=4` , and a`@system-service` syscall filter.\n\n**Credential integrity (pipe mode)**\n\n- **Race condition protection** — vdr trusts the kernel's`%d` dumpable\nflag, not`/proc/pid/auxv` . A handler that reads auxv is vulnerable\n(CVE-2025-4598): an attacker can SIGKILL the crashing SUID process,\nwait for PID recycling, then fork a new non-SUID process to occupy the\nsame PID — causing the handler to read the new process's auxv and\nmisclassify the core dump as non-sensitive. vdr avoids this by not\nreading auxv.\n\n**Credential integrity (socket mode, Linux ≥ 6.16)**\n\n- \n**Kernel-tracked sensitivity** — The kernel's judgment of whether a\ncore dump is sensitive (`PIDFD_COREDUMP_ROOT` , set for SUID/SGID/\nprivileged processes) is stored in kernel data structures tied to the\nprocess ID, not the process's memory. It remains readable even after\nthe crashing process is cleaned up. Individual credentials (UID/GID)\nfrom`pidfd_info` are time-sensitive: they require the crashing\nprocess to remain alive.`core_pipe_limit > 0` makes the kernel\nblock until vdrd closes the connection, keeping the crashing process\nalive during credential retrieval.\n- \n**Recursion prevention** — vdrd marks itself`prctl(PR_SET_DUMPABLE, 0)` to prevent recursive core dumps.\n\n**Socket authentication (socket mode)**\n\nFour layers, all implemented:\n\n- **L1** — Socket file permissions (0600 root:root), verified at startup\n- **L2** —`PIDFD_COREDUMPED` kernel flag (see note below)\n- **L3** —`SO_PEERPIDFD` (kernel-provided process reference, no race)\n- **L4** —`pidfd_info` credentials +`PIDFD_COREDUMP_ROOT`\n\n**On L2**: `PIDFD_COREDUMPED` is set only by the kernel when a process\ncrashes. No userspace API currently exists to set it directly, so a\nnon-crashing process cannot fake this flag. However, this guarantee\nholds only because no such API exists today — it is not a structural\nimpossibility. If a future kernel exposes a way to set the flag from\nuserspace, L2 would weaken. The other layers (L1, L3, L4) would still\napply, but L2 alone would no longer be sufficient.\n\n**Journal hygiene**\n\n- **Minimal metadata** —`cmdline` logging is currently not implemented.\nEnvironment variables and stack contents are not read. If`cmdline` logging is added in the future, it will use a whitelist-based scrub\n(only known-safe fields such as`argv[0]` basename and known valueless\nflags; everything else redacted). Operational fields currently logged:\npath, sizes, build ID, exe (truncated), comm, signal, hostname, pid,\nuid, gid, dumpable, core_limit.\n\n**Filesystem**\n\n- **Symlink hardening** — Storage directory is root-only 0700.`O_CREAT|O_EXCL` rejects symbolic links on the final path component.\n\nSocket mode (Linux ≥ 6.16) currently supports only the `@` (simple)\ncoredump socket protocol. The `@@` (request/ack handshake) protocol is\nnot yet implemented.\n\nvdr is licensed under the GNU General Public License version 2 only\n([GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt)).\n\nSPDX-License-Identifier: GPL-2.0-only", "url": "https://wpnews.pro/news/vdr-an-attempt-at-a-coredump-handler-secure-by-design-requesting-review", "canonical_source": "https://github.com/definitemaybe0/vdr", "published_at": "2026-09-09 10:58:25+00:00", "updated_at": "2026-09-09 11:13:06.596536+00:00", "lang": "en", "topics": ["ai-tools"], "entities": ["vdr", "Voyage Data Recorder", "Rust", "Linux", "CVE-2022-4415", "CVE-2025-4598", "gimli", "libdwarf"], "alternates": {"html": "https://wpnews.pro/news/vdr-an-attempt-at-a-coredump-handler-secure-by-design-requesting-review", "markdown": "https://wpnews.pro/news/vdr-an-attempt-at-a-coredump-handler-secure-by-design-requesting-review.md", "text": "https://wpnews.pro/news/vdr-an-attempt-at-a-coredump-handler-secure-by-design-requesting-review.txt", "jsonld": "https://wpnews.pro/news/vdr-an-attempt-at-a-coredump-handler-secure-by-design-requesting-review.jsonld"}}