4 ms·
I wonder if you could write a LD_PRELOAD library that overrides setenv() (or whatever is used to sanitize the environment) calling the real setenv found via dls
by smcameron 4y ago
I wonder if you could write a LD_PRELOAD library that overrides setenv() (or whatever is used to sanitize the environment) calling the real setenv found via dlsym(RTLD_NEXT, "setenv") in most cases but suppressing the sanitizing of DYLD_LIBRARY_PATH, then run a shell with this library preloaded and Bob's your uncle. Would be kind of gross, and if you legit needed to clear DYLD_LIBRARY_PATH, you'd be out of luck.
- 4ad 4y agoLD_PRELOAD is an ELF thing, macOS has DYLD_INSERT_LIBRARIES, but it doesn't matter because this security feature is implemented in the dynamic loader itself, which also precludes using DYLD_INSERT_LIBRARIES anyway.
- smcameron 4y agoSomething like this maybe: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dlfcn.h> typedef int (*unsetenv_prototype)(const char *name); static unsetenv_prototype real_unsetenv = NULL; int unsetenv(const char *name) { if (!real_unsetenv) { *(void **) &real_unsetenv = dlsym(RTLD_NEXT, "unsetenv"); msg = dlerror(); if (msg) { fprintf(stderr, "Failed to override unsetenv(): %s\n", msg); fflush(stderr); real_unsetenv = NULL; return -1; } } if (strcmp(name, "DYLD_LIBRARY_PATH") == 0) /* suppress sanitizing this */ return 0; return real_unsetenv(name); } Assuming unsetenv() is what is used to do the sanitizing. Might be more likely execve() is what needs to be intercepted though, and by then, it's too late, (unless you just need to jam in a constant value known ahead of time). Edit: another idea. If it only sanitizes certain variables, but not random ones, override setenv() and getenv(), and when passed DYLD_LIBRARY_PATH, instead set/get "MY_SPECIAL_LIBRARY_PATH", which isn't sanitized, and just set that instead of DYLD_LIBRARY_PATH.