diff options
Diffstat (limited to 'stdlib/setenv.h')
-rw-r--r-- | stdlib/setenv.h | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/stdlib/setenv.h b/stdlib/setenv.h index 036f427..7cbf9f2 100644 --- a/stdlib/setenv.h +++ b/stdlib/setenv.h @@ -1,5 +1,5 @@ /* Common declarations for the setenv/getenv family of functions. - Copyright (C) 2024 Free Software Foundation, Inc. + Copyright (C) 2024-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,9 +29,18 @@ of environment values used before. */ struct environ_array { - struct environ_array *next; /* Previously used environment array. */ + /* The actual environment array. Use a separate allocation (and not + a flexible array member) so that calls like free (environ) that + have been encountered in some applications do not crash + immediately. With such a call, if the application restores the + original environ pointer at process start and does not modify the + environment again, a use-after-free situation only occurs during + __libc_freeres, which is only called during memory debugging. + With subsequent setenv calls, there is still heap corruption, but + that happened with the old realloc-based implementation, too. */ + char **array; size_t allocated; /* Number of allocated array elments. */ - char *array[]; /* The actual environment array. */ + struct environ_array *next; /* Previously used environment array. */ }; /* After initialization, and until the user resets environ (perhaps by @@ -44,7 +53,7 @@ static inline bool __environ_is_from_array_list (char **ep) { struct environ_array *eal = atomic_load_relaxed (&__environ_array_list); - return eal != NULL && &eal->array[0] == ep; + return eal != NULL && eal->array == ep; } /* Counter for detecting concurrent modification in unsetenv. |