From f1f48270c92e6b14a5b4b0ea68d53c2f5fc8597c Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 25 Aug 2020 10:48:29 +0200 Subject: [PATCH] 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 --- sys-utils/mount.c | 12 +++++++++++- sys-utils/umount.c | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/sys-utils/mount.c b/sys-utils/mount.c index a87833eee..e5bfd322a 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 056ffb895..b2b0f1a0d 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; }