]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
mount, umount: restore environ[] after suid drop
authorKarel Zak <kzak@redhat.com>
Tue, 25 Aug 2020 08:48:29 +0000 (10:48 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 25 Aug 2020 08:48:29 +0000 (10:48 +0200)
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 <kzak@redhat.com>
sys-utils/mount.c
sys-utils/umount.c

index a87833eee381b4122e61eb4c3fbc6eaa1c44903d..e5bfd322abb0dc2dfe871dc7dc4be17a95144f18 100644 (file)
@@ -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;
 }
 
index 056ffb895a4a04fe7d5abb42f936278d739652f9..b2b0f1a0de1879c1e0f902d65fc1f606a3d06e0a 100644 (file)
@@ -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;
 }