System Programming: Can D binaries be set suid root without the risk of unwanted privilege escalation?
Julian Fondren
julian.fondren at gmail.com
Mon Feb 16 01:24:59 UTC 2026
On Sunday, 15 February 2026 at 09:53:16 UTC, Forum User wrote:
> What I mean is: Are there less well-known environment variables
> or special conditions in the execution environment (e.g.
> resource shortage) which may trigger the dynamic loading of
> foreign code or which execute alternative code paths (e.g. in
> the Garbge Collector, debug facilities) such that the actual
> user of a setuid root binary may create or delete files as root
> or execute other operations they usually cannot execute?
The main thing to check is getenv() calls in your binaries, and
in the dmd/druntime, and in phobos/. At a glance I don't see
anything like Lua's radioactive LUA_INIT, and no getenv calls in
a binary that doesn't perform its own.
The D runtime takes options the CLI (--DRT-) and the environment
(DRT_*) by default, and you can turn that off. See
https://github.com/dlang/dmd/blob/master/druntime/src/rt/config.d
By default, malicious environment variables could maybe
constitute a DOS attack via disabling garbage collection in a D
application, and setuid D binaries could make that worse by
running under less restricted ulimits. In an *extremely unlikely
sequence of events*, a malicious party could repeatedly trigger
the Linux OOM killer this way and eventually disable some
security tool that's obstructing some other path forward.
Practically speaking if you're writing setuid programs in D, I
think you have more much to fear from Phobos's very old (this is
standard) and partial even for its age (this is substandard)
abstraction over the Unix API. For example, suppose you have a
setuid program that edits /home/$user/somedir/somefile . If you
do this straightforwardly in D you open yourself up to a ton of
potential race conditions that can result in you editing or
deleting random files across the filesystem, or pulling secrets
and exposing them to the user. For example, if somefile is a
symlink to /root/.my.cnf which contains the mysql root password,
your setuid program can expose that password, and checks like
std.file.isSymlink are absolutely not going to save you from that
because that function gives you no way to avoid the race
condition.
I don't know for sure that there isn't some D_DO_WHATEVER in some
configuration, but there probably isn't. You also have to check
libraries that you use.
More information about the Digitalmars-d
mailing list