Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAOWsQ2b9msn2mwj2kqUHGW7y09bpPZh5oPwTaoQDuOJbKf_9tQ@mail.gmail.com>
Date: Tue, 30 Sep 2025 16:23:44 -0500
From: Mike Hilgendorf <mike@...gram.dev>
To: musl@...ts.openwall.com
Subject: `unsetenv()` does not always work when run in an `__attribute__((constructor))`
 function

I've failed to reproduce this bug except in rare cases, this is the
smallest I could make it.

Say you want to set LD_PRELOAD to run some code before main() and
unset LD_PRELOAD within that function so it only runs for the parent
process. You might do something like this:


```
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

__attribute__((constructor))
static int preload () {
    if (unsetenv("LD_PRELOAD")) {
        printf("unsetenv errored: %d\n", errno);
    }
    if (getenv("LD_PRELOAD")) {
        printf("LD_PRELOAD was still set\n");
    }
}
```
compiled by running:

musl-gcc preload.c -shared -o preload.so

Now you want to inject this into a binary, say bash, compiled against musl libc

```
cd bash-5.2.37
export CC=musl-gcc
./configure
make

env -i LD_PRELOAD=path/to/preload.so ./bash
```

You will see that LD_PRELOAD was not unset (even in the context of the
ctor function), and LD_PRELOAD is set in the shell.

>From what I can tell, LD_PRELOAD is not special, this is true of other
environment variables. However this is not reproducible with simpler
programs - bash 5.2 is the one where I saw this happen first, and so
far the only program I know that has this issue.

Let me know if I'm doing something very wrong or if there is an easier
reproduction, from scanning bash's source I don't think they're doing
anything strange (they initialize variables with the `char** envp`
passed to main).

I do notice in `dynlink.c` that the stack pointer passed to the
entrypoint by the loader is whatever was passed to the loader, not
accounting for any envp mutations made by calling the DT_INIT_ARRAY
functions. But I don't know if this is actually a problem or not for
the implementation of _start.

- Mike Hilgendorf

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.