Hi As discussed here's a patch for glibc-2.1 that does - don't parse/process ANY dynamic linker env vars if running privileged - if running privileged, dont pass on the dangerous ones to children #I, er, haven't tried compiling it. Feel free to fix it, enhance it, report back etc :) The dynamic linker is _much_ safer with this patch. So choose - test then apply, or do you trust all that parsing....! If this patch doesn't interest anyone then beware, you might want to extract a subset of this patch to fix bugs -Privileged LD_* variables not cleared (currently only LD_PRELOAD and LD_LIBRARAY_PATH are cleared) -LD_PRELOAD allows preload of old buggy libraries if they are lying around in the path. Its allegedly a feature. I call it "bug" Comments? Chris Patched file is glibc/elf/rtld.c --- rtld.c Wed Jul 28 04:14:40 1999 +++ rtld.c Wed Jul 28 04:29:08 1999 @@ -70,6 +70,8 @@ all the entries. */ static void process_envvars (enum mode *modep, int *lazyp); +static void clear_dangerous_envvars(); + int _dl_argc; char **_dl_argv; unsigned int _dl_skip_args; /* Nonzero if we were run directly. */ @@ -332,8 +334,8 @@ ElfW(Addr) *user_entry) { const ElfW(Phdr) *ph; - int lazy; - enum mode mode; + int lazy = 1; + enum mode mode = normal; struct link_map **preloads; unsigned int npreloads; size_t file_size; @@ -346,7 +348,18 @@ hp_timing_t diff; /* Process the environment variable which control the behaviour. */ - process_envvars (&mode, &lazy); + /* ce - don't do _any_ parsing if running privileged */ + if (!__libc_enable_secure) + { + process_envvars (&mode, &lazy); + } + else + { + /* If we ARE secure, clear a few dangerous env vars + * (we don't want children inheriting nasty stuff + */ + clear_dangerous_envvars(); + } /* Set up a flag which tells we are just starting. */ _dl_starting_up = 1; @@ -1278,6 +1291,32 @@ } while (*(dl_debug += len) != '\0'); } + +static void +clear_dangerous_envvars() +{ + static const char *unsecure_envvars[] = + { +#ifdef EXTRA_UNSECURE_ENVVARS + EXTRA_UNSECURE_ENVVARS +#endif + }; + size_t cnt; + + unsetenv ("LD_PRELOAD"); + unsetenv ("LD_LIBRARY_PATH"); + unsetenv ("LD_DEBUG"); + unsetenv ("LD_ORIGIN_PATH"); + unsetenv ("LD_DEBUG_OUTPUT"); + unsetenv ("LD_PROFILE"); + unsetenv ("LD_PROFILE_OUTPUT"); + + for (cnt = 0; + cnt < sizeof (unsecure_envvars) / sizeof (unsecure_envvars[0]); + ++cnt) + unsetenv (unsecure_envvars[cnt]); +} + /* Process all environments variables the dynamic linker must recognize. Since all of them start with `LD_' we are a bit smarter while finding