FreeBSD Linuxulator AT_SECURE=0 Local Privilege Escalation via LD_PRELOAD (CVE-2026-49413)
by ii4gsp · 2026-07-05
- Severity
- High
- CVE
- CVE-2026-49413
- Category
- binary
- Affected product
- FreeBSD Linux compatibility layer ("Linuxulator", linux/linux64 kernel module) executing Linux setuid-root binaries under /compat/linux/
- Affected versions
- Not specified in source (README is only a result screenshot)
- Disclosed
- 2026-07-05
- Patch status
- unpatched
References
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-07 |
| Author / Researcher | ii4gsp |
| CVE / Advisory | CVE-2026-49413 |
| Category | binary |
| Severity | High |
| CVSS Score | Not specified in source |
| Status | PoC |
| Tags | freebsd, linuxulator, at_secure, ld_preload, setuid, local-privilege-escalation, c |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | FreeBSD Linux compatibility layer (“Linuxulator”, linux/linux64 kernel module) executing Linux setuid-root binaries under /compat/linux/ |
| Versions Affected | Not specified in source (README is only a result screenshot) |
| Language / Platform | C, FreeBSD (native syscalls issued directly via inline syscall instructions) |
| Authentication Required | Local-only |
| Network Access Required | No |
Summary
exploit.c is a local privilege-escalation PoC targeting FreeBSD’s Linux compatibility subsystem. It detects whether the Linuxulator is loaded and glibc’s dynamic linker is present under /compat/linux/, locates a setuid-root Linux binary within that tree, and then uses LD_SHOW_AUXV to probe whether the process’s AT_SECURE auxiliary vector value is incorrectly 0 for that setuid binary. If so, the loader will honor LD_PRELOAD even though the process runs with an elevated effective UID — the PoC builds a minimal ELF shared object at runtime (raw syscall instructions with no libc), sets LD_PRELOAD to it, and re-executes the setuid target, causing its constructor to run with root’s effective UID and spawn a root shell.
Vulnerability Details
Root Cause
Linux binaries executed through FreeBSD’s Linuxulator are supposed to have AT_SECURE set to 1 whenever they are setuid/setgid, which tells the dynamic linker to ignore security-sensitive environment variables such as LD_PRELOAD. This PoC demonstrates that under the vulnerable condition, AT_SECURE is instead reported as 0 for a setuid-root Linux binary run under the compatibility layer, so glibc’s loader honors LD_PRELOAD and loads attacker-supplied code into the process before it drops privileges.
Attack Vector
- Confirm the Linuxulator kernel module (
linux/linux64) is loaded and glibc’sld-linux(-x86-64).so.2is present under/compat/linux/. - Enumerate common Linux setuid-root binaries under
/compat/linux/(e.g.su,sudo,passwd,pkexec,mount) and pick one that is actually setuid-root. - Run that binary with
LD_SHOW_AUXV=1and inspect its stdout/stderr for theAT_SECUREvalue; if it is0, the binary’s setuid dynamic linking is not hardened against environment-based code injection. - Compile a minimal shared object (
evil.so) at runtime whose ELF constructor executes raw syscalls (no libc dependency) to print the effective UID and, if it is0(root), spawn/bin/shviaexecve. - Set
LD_PRELOAD=/tmp/.poc_evil.soandexecvethe vulnerable setuid-root target; becauseAT_SECUREwas0, the dynamic linker loads and runsevil.so’s constructor with root’s effective UID, yielding a root shell.
Impact
Local unprivileged user on a FreeBSD system with the Linuxulator enabled can escalate to root by hijacking any Linux setuid-root binary made available under /compat/linux/.
Environment / Lab Setup
Target: FreeBSD host with the linux64 (or linux) kernel module loaded, glibc runtime installed under /compat/linux/, and at least one setuid-root Linux binary present in that tree
Attacker: Unprivileged local shell on the same FreeBSD host, a C compiler (cc) and brandelf available for building the injected shared object
Proof of Concept
PoC Script
See
exploit.cin this folder.
| |
The program prints environment-check results (Linuxulator loaded, glibc present, candidate setuid binary found), tests the target’s AT_SECURE value via LD_SHOW_AUXV, and — if vulnerable — compiles /tmp/.poc_evil.so, sets LD_PRELOAD to it, and re-execs the setuid-root target; if the resulting effective UID is 0, it drops into a root /bin/sh.
Detection & Indicators of Compromise
Signs of compromise:
- A root shell spawned as a child of a Linux compatibility-layer setuid binary (
su,sudo,passwd, etc.) with no corresponding legitimate admin action - Presence of ad hoc
.sofiles compiled just before privilege escalation, especially under/tmp - Process accounting showing
LD_PRELOADset in the environment of a setuid-root process invocation
Remediation
| Action | Detail |
|---|---|
| Primary fix | No vendor patch confirmed in source — the Linuxulator must correctly set AT_SECURE=1 in the auxiliary vector passed to any setuid/setgid Linux binary it executes, so glibc’s loader ignores LD_PRELOAD and other security-sensitive environment variables |
| Interim mitigation | Avoid deploying setuid-root Linux binaries under /compat/linux/, or restrict/monitor the Linuxulator’s use on multi-user systems until patched; strip setuid bits from non-essential Linux binaries in the compatibility tree |
References
Notes
Mirrored from https://github.com/ii4gsp/CVE-2026-49413 on 2026-07-05.
| |