From: Karel Zak Date: Tue, 25 Aug 2020 08:48:29 +0000 (+0200) Subject: mount, umount: restore environ[] after suid drop X-Git-Tag: v2.37-rc1~508 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f1f48270c92e6b14a5b4b0ea68d53c2f5fc8597c;p=thirdparty%2Futil-linux.git mount, umount: restore environ[] after suid drop The commands mount and umount sanitize environment variables as it works with suid permissions by default. Since v2.36 it's possible that the commands drop the permissions and continue as regular user. It seems we also need to restore the original environ to keep things consistent for users (e.g. HOME=). The implementation is pretty simple -- it keeps in memory removed variables and use it after switch to non-suid mode. Addresses: https://github.com/karelzak/util-linux/issues/880 Signed-off-by: Karel Zak --- diff --git a/sys-utils/mount.c b/sys-utils/mount.c index a87833eee3..e5bfd322ab 100644 --- a/sys-utils/mount.c +++ b/sys-utils/mount.c @@ -45,6 +45,8 @@ #define OPTUTILS_EXIT_CODE MNT_EX_USAGE #include "optutils.h" +static struct ul_env_list *envs_removed; + static int mk_exit_code(struct libmnt_context *cxt, int rc); static void suid_drop(struct libmnt_context *cxt) @@ -65,6 +67,13 @@ static void suid_drop(struct libmnt_context *cxt) errx(MNT_EX_FAIL, _("drop permissions failed.")); mnt_context_force_unrestricted(cxt); + + /* restore "bad" environment variables */ + if (envs_removed) { + env_list_setenv(envs_removed); + env_list_free(envs_removed); + envs_removed = NULL; + } } static void __attribute__((__noreturn__)) mount_print_version(void) @@ -652,7 +661,7 @@ int main(int argc, char **argv) }; int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; - sanitize_env(); + __sanitize_env(&envs_removed); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -991,6 +1000,7 @@ int main(int argc, char **argv) success_message(cxt); done: mnt_free_context(cxt); + env_list_free(envs_removed); return rc; } diff --git a/sys-utils/umount.c b/sys-utils/umount.c index 056ffb895a..b2b0f1a0de 100644 --- a/sys-utils/umount.c +++ b/sys-utils/umount.c @@ -43,6 +43,7 @@ #include "optutils.h" static int quiet; +static struct ul_env_list *envs_removed; static int table_parser_errcb(struct libmnt_table *tb __attribute__((__unused__)), const char *filename, int line) @@ -130,6 +131,13 @@ static void suid_drop(struct libmnt_context *cxt) errx(MNT_EX_FAIL, _("drop permissions failed.")); mnt_context_force_unrestricted(cxt); + + /* restore "bad" environment variables */ + if (envs_removed) { + env_list_setenv(envs_removed); + env_list_free(envs_removed); + envs_removed = NULL; + } } static void success_message(struct libmnt_context *cxt) @@ -486,7 +494,7 @@ int main(int argc, char **argv) }; int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; - sanitize_env(); + __sanitize_env(&envs_removed); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -621,6 +629,8 @@ int main(int argc, char **argv) } mnt_free_context(cxt); + env_list_free(envs_removed); + return (rc < 256) ? rc : 255; }