diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -403,7 +403,12 @@ n = *m; v = strchr(n, '='); if (v == NULL) { - /* corrupt environment? */ + /* + * Corrupt environment? Assert that we're not setuid, + * because this should specifically be protected against + * on security boundaries like that. + */ + assert(trust); continue; } if (v - n == (ptrdiff_t)name_len && @@ -413,6 +418,19 @@ return (NULL); } +static void +rtld_check_untrusted_env(char **env) +{ + char **m; + + for (m = env; *m != NULL; m++) { + if (strchr(*m, '=') == NULL) { + _rtld_error("environment corrupt; aborting"); + rtld_die(); + } + } +} + static void rtld_init_env_vars_for_prefix(char **env, const char *env_prefix) { @@ -431,7 +449,12 @@ n += prefix_len; v = strchr(n, '='); if (v == NULL) { - /* corrupt environment? */ + /* + * Corrupt environment? Assert that we're not setuid, + * because this should specifically be protected against + * on security boundaries like that. + */ + assert(trust); continue; } for (i = 0; i < (int)nitems(ld_env_vars); i++) { @@ -453,6 +476,8 @@ static void rtld_init_env_vars(char **env) { + if (!trust) + rtld_check_untrusted_env(env); rtld_init_env_vars_for_prefix(env, ld_env_prefix); }