aboutsummaryrefslogtreecommitdiff
path: root/csu
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2025-01-22 13:48:56 +0100
committerFlorian Weimer <fweimer@redhat.com>2025-01-23 17:43:15 +0100
commitb62759db04b8ed7f829c06f1d7c3b8fb70616493 (patch)
treeec0a519968d10625281774ffe06ed73ad0feaa6f /csu
parent76c3f7f81b7b99fedbff6edc07cddff59e2ae6e2 (diff)
downloadglibc-b62759db04b8ed7f829c06f1d7c3b8fb70616493.tar.xz
glibc-b62759db04b8ed7f829c06f1d7c3b8fb70616493.zip
stdlib: Support malloc-managed environ arrays for compatibility
Some applications set environ to a heap-allocated pointer, call setenv (expecting it to call realloc), free environ, and then restore the original environ pointer. This breaks after commit 7a61e7f557a97ab597d6fca5e2d1f13f65685c61 ("stdlib: Make getenv thread-safe in more cases") because after the setenv call, the environ pointer does not point to the start of a heap allocation. Instead, setenv creates a separate allocation and changes environ to point into that. This means that the free call in the application results in heap corruption. The interim approach was more compatible with other libcs because it does not assume that the incoming environ pointer is allocated as if by malloc (if it was written by the application). However, it seems to be more important to stay compatible with previous glibc version: assume the incoming pointer is heap allocated, and preserve this property after setenv calls. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'csu')
-rw-r--r--csu/init-first.c1
-rw-r--r--csu/libc-start.c1
2 files changed, 2 insertions, 0 deletions
diff --git a/csu/init-first.c b/csu/init-first.c
index e35e4ce84f..0ad6f75dcd 100644
--- a/csu/init-first.c
+++ b/csu/init-first.c
@@ -61,6 +61,7 @@ _init_first (int argc, char **argv, char **envp)
__libc_argc = argc;
__libc_argv = argv;
__environ = envp;
+ __environ_startup = envp;
#ifndef SHARED
/* First the initialization which normally would be done by the
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 6f3d52e223..4e15b6191d 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -244,6 +244,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
char **ev = &argv[argc + 1];
__environ = ev;
+ __environ_startup = ev;
/* Store the lowest stack address. This is done in ld.so if this is
the code for the DSO. */