mirror of
https://git.proxmox.com/git/wasi-libc
synced 2025-07-23 20:08:19 +00:00

* Link `populate_environ` only if we actually need environment variables. This avoids linking in the environment variable initialization code, and the __wasi_environ_sizes_get and __wasi_environ_get imports, in programs that don't use environment variables. This also removes the "___environ" (three underscores) alias symbol, which is only in musl for backwards compatibility. * Switch to //-style comments. * If malloc fails, don't leave `__environ` pointing to an uninitialized buffer. * Fix a memory leak if one malloc succeeds and the other fails. * Use calloc to handle multiplication overflow. This also handles the NULL terminator. * Don't initialize __environ until everything has succeeded. * Avoid leaking in case __wasi_environ_get fails. * Handle overflow in the add too. * Add #include <stdlib.h> for malloc etc. * If the environment is empty, don't allocate any memory.
58 lines
1.8 KiB
C
58 lines
1.8 KiB
C
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <wasi/core.h>
|
|
#include <wasi/libc.h>
|
|
#include <wasi/libc-internal.h>
|
|
|
|
char **__environ = NULL;
|
|
extern __typeof(__environ) _environ __attribute__((weak, alias("__environ")));
|
|
extern __typeof(__environ) environ __attribute__((weak, alias("__environ")));
|
|
|
|
// This function is referenced by a weak symbol in crt1.c, and we define
|
|
// it here in the same source file as __environ, so that this function is
|
|
// linked in iff environment variable support is used.
|
|
__wasi_errno_t __wasilibc_populate_environ(void) {
|
|
__wasi_errno_t err;
|
|
|
|
// Get the sizes of the arrays we'll have to create to copy in the environment.
|
|
size_t environ_count;
|
|
size_t environ_buf_size;
|
|
err = __wasi_environ_sizes_get(&environ_count, &environ_buf_size);
|
|
if (err != __WASI_ESUCCESS) {
|
|
return err;
|
|
}
|
|
if (environ_count == 0) {
|
|
return __WASI_ESUCCESS;
|
|
}
|
|
|
|
// Add 1 for the NULL pointer to mark the end, and check for overflow.
|
|
size_t num_ptrs = environ_count + 1;
|
|
if (num_ptrs == 0) {
|
|
return __WASI_ENOMEM;
|
|
}
|
|
|
|
// Allocate memory for storing the environment chars.
|
|
char *environ_buf = malloc(environ_buf_size);
|
|
if (environ_buf == NULL) {
|
|
return __WASI_ENOMEM;
|
|
}
|
|
|
|
// Allocate memory for the array of pointers. This uses `calloc` both to
|
|
// handle overflow and to initialize the NULL pointer at the end.
|
|
char **environ_ptrs = calloc(num_ptrs, sizeof(char *));
|
|
if (environ_ptrs == NULL) {
|
|
free(environ_buf);
|
|
return __WASI_ENOMEM;
|
|
}
|
|
|
|
// Fill the environment chars, and the __environ array with pointers into those chars.
|
|
err = __wasi_environ_get(environ_ptrs, environ_buf);
|
|
if (err == __WASI_ESUCCESS) {
|
|
__environ = environ_ptrs;
|
|
} else {
|
|
free(environ_buf);
|
|
free(environ_ptrs);
|
|
}
|
|
return err;
|
|
}
|