]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
include/c: add drop_permissions(), consolidate UID/GID reset
authorKarel Zak <kzak@redhat.com>
Mon, 21 Jun 2021 10:25:31 +0000 (12:25 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 21 Jun 2021 10:25:31 +0000 (12:25 +0200)
Fixes: https://github.com/karelzak/util-linux/issues/1354
Signed-off-by: Karel Zak <kzak@redhat.com>
include/c.h
lib/canonicalize.c
libblkid/src/topology/dm.c
libblkid/src/topology/lvm.c
libmount/src/context_mount.c
libmount/src/context_umount.c
sys-utils/eject.c
sys-utils/mount.c
sys-utils/swapon.c
sys-utils/umount.c
text-utils/more.c

index e7842c1064ae770d94c581ea653dabf85b342983..c1e4c5ffc92b0f9c648f379fb7465e5f714b88f1 100644 (file)
@@ -16,6 +16,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <sys/types.h>
+#include <grp.h>
 
 #include <assert.h>
 
@@ -335,6 +337,28 @@ static inline size_t get_hostname_max(void)
        return 64;
 }
 
+
+static inline int drop_permissions(void)
+{
+       errno = 0;
+
+       /* drop supplementary groups */
+       if (setgroups(0, NULL) != 0)
+               goto fail;
+
+       /* drop GID */
+       if (setgid(getgid()) < 0)
+               goto fail;
+
+       /* drop UID */
+       if (setuid(getuid()) < 0)
+               goto fail;
+
+       return 0;
+fail:
+       return errno ? -errno : -1;
+}
+
 /*
  * The usleep function was marked obsolete in POSIX.1-2001 and was removed
  * in POSIX.1-2008.  It was replaced with nanosleep() that provides more
index e101c5b7a8af6af57f52d10562280cc2e221ccc8..6f85b47e5e12133c28eb1341821d9d9c66d87e0c 100644 (file)
@@ -170,8 +170,7 @@ char *canonicalize_path_restricted(const char *path)
                pipes[0] = -1;
                errno = 0;
 
-               /* drop permissions */
-               if (setgid(getgid()) < 0 || setuid(getuid()) < 0)
+               if (drop_permissions() != 0)
                        canonical = NULL;       /* failed */
                else {
                        char *dmname = NULL;
index 37fce6d6294a212bb5060ed38e6a5d0c1ac89738..b210a805bd6645850d9caa2b287299ee60597aad 100644 (file)
@@ -73,10 +73,7 @@ static int probe_dm_tp(blkid_probe pr,
                if (dmpipe[1] != STDOUT_FILENO)
                        dup2(dmpipe[1], STDOUT_FILENO);
 
-               /* The libblkid library could linked with setuid programs */
-               if (setgid(getgid()) < 0)
-                        exit(1);
-               if (setuid(getuid()) < 0)
+               if (drop_permissions() != 0)
                         exit(1);
 
                snprintf(maj, sizeof(maj), "%d", major(devno));
index bd079d47ba6ad93b5760d3309ca3aa0ffe83a58a..8b0c0feea979d9f9d3468d867844d773f1da4841 100644 (file)
@@ -82,10 +82,7 @@ static int probe_lvm_tp(blkid_probe pr,
                if (lvpipe[1] != STDOUT_FILENO)
                        dup2(lvpipe[1], STDOUT_FILENO);
 
-               /* The libblkid library could linked with setuid programs */
-               if (setgid(getgid()) < 0)
-                        exit(1);
-               if (setuid(getuid()) < 0)
+               if (drop_permissions() != 0)
                         exit(1);
 
                lvargv[0] = cmd;
index 8c0a20e55f68887ee71435613cd16f595c5bbcee..55ebf79451deb48893bb15fbc0cb7ba77e2cb1ef 100644 (file)
@@ -645,10 +645,7 @@ static int exec_helper(struct libmnt_context *cxt)
                const char *args[14], *type;
                int i = 0;
 
-               if (setgid(getgid()) < 0)
-                       _exit(EXIT_FAILURE);
-
-               if (setuid(getuid()) < 0)
+               if (drop_permissions() != 0)
                        _exit(EXIT_FAILURE);
 
                if (!mnt_context_switch_origin_ns(cxt))
index 57eda75be74ca1dc652327316af570233519eb61..173637a15ad20dbcd0d1eb02bc332fd80befb7ab 100644 (file)
@@ -696,10 +696,7 @@ static int exec_helper(struct libmnt_context *cxt)
                const char *args[12], *type;
                int i = 0;
 
-               if (setgid(getgid()) < 0)
-                       _exit(EXIT_FAILURE);
-
-               if (setuid(getuid()) < 0)
+               if (drop_permissions() != 0)
                        _exit(EXIT_FAILURE);
 
                if (!mnt_context_switch_origin_ns(cxt))
index ca5fbc38026246b288a1636897782643803ccc65..457ce0d081f08758763e4ec57beead44a674651c 100644 (file)
@@ -658,12 +658,8 @@ static void umount_one(const struct eject_control *ctl, const char *name)
 
        switch (fork()) {
        case 0: /* child */
-               if (setgid(getgid()) < 0)
-                       err(EXIT_FAILURE, _("cannot set group id"));
-
-               if (setuid(getuid()) < 0)
-                       err(EXIT_FAILURE, _("cannot set user id"));
-
+               if (drop_permissions() != 0)
+                       err(EXIT_FAILURE, _("drop permissions failed"));
                if (ctl->p_option)
                        execl("/bin/umount", "/bin/umount", name, "-n", (char *)NULL);
                else
index c2dbcdcedca0a3779f3d1df4762d55a8ffbf08cf..a0e718d72cea76fc67cf3f4d7636dc65729c59c7 100644 (file)
@@ -54,13 +54,8 @@ static void suid_drop(struct libmnt_context *cxt)
        const uid_t ruid = getuid();
        const uid_t euid = geteuid();
 
-       if (ruid != 0 && euid == 0) {
-               if (setgid(getgid()) < 0)
-                       err(MNT_EX_FAIL, _("setgid() failed"));
-
-               if (setuid(getuid()) < 0)
-                       err(MNT_EX_FAIL, _("setuid() failed"));
-       }
+       if (ruid != 0 && euid == 0 && drop_permissions() != 0)
+               err(MNT_EX_FAIL, _("drop permissions failed"));
 
        /* be paranoid and check it, setuid(0) has to fail */
        if (ruid != 0 && setuid(0) == 0)
index 0f47d85168325a19fe652b47ef0493c3c4f7c442..da836c47ed19e595d2d22dc098b9c430b80954d1 100644 (file)
@@ -333,13 +333,8 @@ static int swap_reinitialize(struct swap_device *dev)
                return -1;
 
        case 0: /* child */
-               if (geteuid() != getuid()) {
-                       /* in case someone uses swapon as setuid binary */
-                       if (setgid(getgid()) < 0)
-                               exit(EXIT_FAILURE);
-                       if (setuid(getuid()) < 0)
-                               exit(EXIT_FAILURE);
-               }
+               if (geteuid() != getuid() && drop_permissions() != 0)
+                       exit(EXIT_FAILURE);
 
                cmd[idx++] = "mkswap";
                if (dev->label) {
index ec357d0dfe61b9bc8833c4c6f4259e4eaf62e961..f5931767cc5f3de577e13d9559bdb2d125aeee21 100644 (file)
@@ -118,13 +118,8 @@ static void suid_drop(struct libmnt_context *cxt)
        const uid_t ruid = getuid();
        const uid_t euid = geteuid();
 
-       if (ruid != 0 && euid == 0) {
-               if (setgid(getgid()) < 0)
-                       err(MNT_EX_FAIL, _("setgid() failed"));
-
-               if (setuid(getuid()) < 0)
-                       err(MNT_EX_FAIL, _("setuid() failed"));
-       }
+       if (ruid != 0 && euid == 0 && drop_permissions() != 0)
+               err(MNT_EX_FAIL, _("drop permissions failed"));
 
        /* be paranoid and check it, setuid(0) has to fail */
        if (ruid != 0 && setuid(0) == 0)
index fe5b1d2459f77cc1ac47a01da8aa344e2773c27d..3f45d1114c222c9f7b23226c1a207c1609aa2785 100644 (file)
@@ -1250,12 +1250,9 @@ static void __attribute__((__format__ (__printf__, 3, 4)))
                }
                va_end(argp);
 
-               if (geteuid() != getuid() || getegid() != getgid()) {
-                       if (setgid(getgid()) < 0)
-                               err(EXIT_FAILURE, _("setgid failed"));
-                       if (setuid(getuid()) < 0)
-                               err(EXIT_FAILURE, _("setuid failed"));
-               }
+               if ((geteuid() != getuid() || getegid() != getgid())
+                   && drop_permissions() != 0)
+                       err(EXIT_FAILURE, _("drop permissions failed"));
 
                execvp(cmd, args);
                errsv = errno;