Bash Exported-Function Path Backdoor
In Bash versions before 4.2-048, the shell accepts function definitions whose names contain slashes — including names that are byte-for-byte absolute paths to executables. Combined with export -f, this lets an unprivileged user plant a shell function in the environment that a privileged process’s child shell will run instead of the real binary at that path. 1
The technique
function /path/to/executable { /bin/bash -p; }
export -f /path/to/executableWhen a SUID/SGID program (or any privileged process) later relies on the current shell to invoke /path/to/executable — via system(), popen(), or a child script — the exported function shadows the real command and runs with the caller’s effective privileges. -p preserves the elevated euid into the interactive shell (see suid-shell-executable).
Why it worked
Two Bash behaviors intersect:
- Functions could be named like paths. POSIX requires function names to be “name”-tokens (no slashes), but Bash accepted them anyway. A privileged helper calling
/usr/bin/foowould resolve the function/usr/bin/foobefore ever consulting the filesystem. 2 - Exported functions ride the environment.
export -fserializes the function into an environment variable, so any child Bash inherits it — no write access to PATH directories needed, unlike the relative-path variant in suid-shell-executable. 3
Bash 4.2-048 (2010) tightened function-name validation, and the later Shellshock-era changes (2014) further restricted how exported functions are imported into privileged shells — functions are no longer inherited at all when euid ≠ ruid (the same startup sanitization that neutralized the PS4 trick). 4
Defensive lessons
- SUID binaries should never call out through a shell; use absolute paths with direct
exec*()calls. 5 - Sanitizing inherited shell state at privilege boundaries is Bash’s job now, but the broader pattern — the environment is untrusted input to a privileged process — is the same one that drives
LD_PRELOAD/LD_LIBRARY_PATHsanitization (see ld-preload-trick) and sudo’senv_resetdefault.
Sources
Related: bash-ps4-prompt-exploit, suid-shell-executable, ld-preload-trick, unix-permissions