From: Karel Zak Date: Wed, 28 Aug 2024 10:08:30 +0000 (+0200) Subject: su: use lib/env.c for --whitelist-environment X-Git-Tag: v2.42-start~214^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=65f1d00e7d0c559517e56f990425e5b583954954;p=thirdparty%2Futil-linux.git su: use lib/env.c for --whitelist-environment Do not use a local implementation, instead use code from the lib/ directory. Signed-off-by: Karel Zak --- diff --git a/login-utils/su-common.c b/login-utils/su-common.c index 536557535..12c933633 100644 --- a/login-utils/su-common.c +++ b/login-utils/su-common.c @@ -144,8 +144,7 @@ struct su_context { pid_t child; /* fork() baby */ int childstatus; /* wait() status */ - char **env_whitelist_names; /* environment whitelist */ - char **env_whitelist_vals; + struct ul_env_list *env_whitelist; /* environment whitelist */ struct sigaction oldact[SIGNALS_IDX_COUNT]; /* original sigactions indexed by SIG*_IDX */ #ifdef USE_PTY @@ -663,56 +662,6 @@ static void create_watching_parent(struct su_context *su) exit(status); } -/* Adds @name from the current environment to the whitelist. If @name is not - * set then nothing is added to the whitelist and returns 1. - */ -static int env_whitelist_add(struct su_context *su, const char *name) -{ - const char *env = getenv(name); - - if (!env) - return 1; - if (strv_extend(&su->env_whitelist_names, name)) - err_oom(); - if (strv_extend(&su->env_whitelist_vals, env)) - err_oom(); - return 0; -} - -static int env_whitelist_setenv(struct su_context *su, int overwrite) -{ - char **one; - size_t i = 0; - int rc; - - STRV_FOREACH(one, su->env_whitelist_names) { - rc = setenv(*one, su->env_whitelist_vals[i], overwrite); - if (rc) - return rc; - i++; - } - - return 0; -} - -/* Creates (add to) whitelist from comma delimited string */ -static int env_whitelist_from_string(struct su_context *su, const char *str) -{ - char **all = strv_split(str, ","); - char **one; - - if (!all) { - if (errno == ENOMEM) - err_oom(); - return -EINVAL; - } - - STRV_FOREACH(one, all) - env_whitelist_add(su, *one); - strv_free(all); - return 0; -} - static void setenv_path(const struct passwd *pw) { int rc; @@ -743,7 +692,7 @@ static void modify_environment(struct su_context *su, const char *shell) */ if (su->simulate_login) { /* leave TERM unchanged */ - env_whitelist_add(su, "TERM"); + su->env_whitelist = env_list_add_getenv(su->env_whitelist, "TERM", NULL); /* Note that original su(1) has allocated environ[] by malloc * to the number of expected variables. This seems unnecessary @@ -768,7 +717,8 @@ static void modify_environment(struct su_context *su, const char *shell) xsetenv("LOGNAME", pw->pw_name, 1); /* apply all from whitelist, but no overwrite */ - env_whitelist_setenv(su, 0); + if (env_list_setenv(su->env_whitelist, 0) != 0) + err(EXIT_FAILURE, _("failed to set environment variables")); /* Set HOME, SHELL, and (if not becoming a superuser) USER and LOGNAME. */ @@ -787,6 +737,9 @@ static void modify_environment(struct su_context *su, const char *shell) } supam_export_environment(su); + + env_list_free(su->env_whitelist); + su->env_whitelist = NULL; } static void init_groups(struct su_context *su, gid_t *groups, size_t ngroups) @@ -1123,7 +1076,7 @@ int su_main(int argc, char **argv, int mode) break; case 'w': - env_whitelist_from_string(su, optarg); + su->env_whitelist = env_list_add_getenvs(su->env_whitelist, optarg); break; case 'P':