include/c: add drop_permissions(), consolidate UID/GID reset

Fixes: https://github.com/karelzak/util-linux/issues/1354
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2021-06-21 12:25:31 +02:00
parent 0272f2ef98
commit 17fc8693cd
11 changed files with 40 additions and 51 deletions

View 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

View 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;

View 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));

View 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;

View 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))

View 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))

View 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

View 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)

View 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) {

View 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)

View 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;