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:
parent
155b79d38e
commit
86328e78ea
24
include/c.h
24
include/c.h
|
@ -16,6 +16,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <grp.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
@ -335,6 +337,28 @@ static inline size_t get_hostname_max(void)
|
||||||
return 64;
|
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
|
* 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
|
* in POSIX.1-2008. It was replaced with nanosleep() that provides more
|
||||||
|
|
|
@ -170,8 +170,7 @@ char *canonicalize_path_restricted(const char *path)
|
||||||
pipes[0] = -1;
|
pipes[0] = -1;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
/* drop permissions */
|
if (drop_permissions() != 0)
|
||||||
if (setgid(getgid()) < 0 || setuid(getuid()) < 0)
|
|
||||||
canonical = NULL; /* failed */
|
canonical = NULL; /* failed */
|
||||||
else {
|
else {
|
||||||
char *dmname = NULL;
|
char *dmname = NULL;
|
||||||
|
|
|
@ -73,10 +73,7 @@ static int probe_dm_tp(blkid_probe pr,
|
||||||
if (dmpipe[1] != STDOUT_FILENO)
|
if (dmpipe[1] != STDOUT_FILENO)
|
||||||
dup2(dmpipe[1], STDOUT_FILENO);
|
dup2(dmpipe[1], STDOUT_FILENO);
|
||||||
|
|
||||||
/* The libblkid library could linked with setuid programs */
|
if (drop_permissions() != 0)
|
||||||
if (setgid(getgid()) < 0)
|
|
||||||
exit(1);
|
|
||||||
if (setuid(getuid()) < 0)
|
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
snprintf(maj, sizeof(maj), "%d", major(devno));
|
snprintf(maj, sizeof(maj), "%d", major(devno));
|
||||||
|
|
|
@ -82,10 +82,7 @@ static int probe_lvm_tp(blkid_probe pr,
|
||||||
if (lvpipe[1] != STDOUT_FILENO)
|
if (lvpipe[1] != STDOUT_FILENO)
|
||||||
dup2(lvpipe[1], STDOUT_FILENO);
|
dup2(lvpipe[1], STDOUT_FILENO);
|
||||||
|
|
||||||
/* The libblkid library could linked with setuid programs */
|
if (drop_permissions() != 0)
|
||||||
if (setgid(getgid()) < 0)
|
|
||||||
exit(1);
|
|
||||||
if (setuid(getuid()) < 0)
|
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
lvargv[0] = cmd;
|
lvargv[0] = cmd;
|
||||||
|
|
|
@ -645,10 +645,7 @@ static int exec_helper(struct libmnt_context *cxt)
|
||||||
const char *args[14], *type;
|
const char *args[14], *type;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (setgid(getgid()) < 0)
|
if (drop_permissions() != 0)
|
||||||
_exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
if (setuid(getuid()) < 0)
|
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
|
|
||||||
if (!mnt_context_switch_origin_ns(cxt))
|
if (!mnt_context_switch_origin_ns(cxt))
|
||||||
|
|
|
@ -696,10 +696,7 @@ static int exec_helper(struct libmnt_context *cxt)
|
||||||
const char *args[12], *type;
|
const char *args[12], *type;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (setgid(getgid()) < 0)
|
if (drop_permissions() != 0)
|
||||||
_exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
if (setuid(getuid()) < 0)
|
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
|
|
||||||
if (!mnt_context_switch_origin_ns(cxt))
|
if (!mnt_context_switch_origin_ns(cxt))
|
||||||
|
|
|
@ -658,12 +658,8 @@ static void umount_one(const struct eject_control *ctl, const char *name)
|
||||||
|
|
||||||
switch (fork()) {
|
switch (fork()) {
|
||||||
case 0: /* child */
|
case 0: /* child */
|
||||||
if (setgid(getgid()) < 0)
|
if (drop_permissions() != 0)
|
||||||
err(EXIT_FAILURE, _("cannot set group id"));
|
err(EXIT_FAILURE, _("drop permissions failed"));
|
||||||
|
|
||||||
if (setuid(getuid()) < 0)
|
|
||||||
err(EXIT_FAILURE, _("cannot set user id"));
|
|
||||||
|
|
||||||
if (ctl->p_option)
|
if (ctl->p_option)
|
||||||
execl("/bin/umount", "/bin/umount", name, "-n", (char *)NULL);
|
execl("/bin/umount", "/bin/umount", name, "-n", (char *)NULL);
|
||||||
else
|
else
|
||||||
|
|
|
@ -54,13 +54,8 @@ static void suid_drop(struct libmnt_context *cxt)
|
||||||
const uid_t ruid = getuid();
|
const uid_t ruid = getuid();
|
||||||
const uid_t euid = geteuid();
|
const uid_t euid = geteuid();
|
||||||
|
|
||||||
if (ruid != 0 && euid == 0) {
|
if (ruid != 0 && euid == 0 && drop_permissions() != 0)
|
||||||
if (setgid(getgid()) < 0)
|
err(MNT_EX_FAIL, _("drop permissions failed"));
|
||||||
err(MNT_EX_FAIL, _("setgid() failed"));
|
|
||||||
|
|
||||||
if (setuid(getuid()) < 0)
|
|
||||||
err(MNT_EX_FAIL, _("setuid() failed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* be paranoid and check it, setuid(0) has to fail */
|
/* be paranoid and check it, setuid(0) has to fail */
|
||||||
if (ruid != 0 && setuid(0) == 0)
|
if (ruid != 0 && setuid(0) == 0)
|
||||||
|
|
|
@ -333,13 +333,8 @@ static int swap_reinitialize(struct swap_device *dev)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
case 0: /* child */
|
case 0: /* child */
|
||||||
if (geteuid() != getuid()) {
|
if (geteuid() != getuid() && drop_permissions() != 0)
|
||||||
/* in case someone uses swapon as setuid binary */
|
exit(EXIT_FAILURE);
|
||||||
if (setgid(getgid()) < 0)
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
if (setuid(getuid()) < 0)
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd[idx++] = "mkswap";
|
cmd[idx++] = "mkswap";
|
||||||
if (dev->label) {
|
if (dev->label) {
|
||||||
|
|
|
@ -118,13 +118,8 @@ static void suid_drop(struct libmnt_context *cxt)
|
||||||
const uid_t ruid = getuid();
|
const uid_t ruid = getuid();
|
||||||
const uid_t euid = geteuid();
|
const uid_t euid = geteuid();
|
||||||
|
|
||||||
if (ruid != 0 && euid == 0) {
|
if (ruid != 0 && euid == 0 && drop_permissions() != 0)
|
||||||
if (setgid(getgid()) < 0)
|
err(MNT_EX_FAIL, _("drop permissions failed"));
|
||||||
err(MNT_EX_FAIL, _("setgid() failed"));
|
|
||||||
|
|
||||||
if (setuid(getuid()) < 0)
|
|
||||||
err(MNT_EX_FAIL, _("setuid() failed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* be paranoid and check it, setuid(0) has to fail */
|
/* be paranoid and check it, setuid(0) has to fail */
|
||||||
if (ruid != 0 && setuid(0) == 0)
|
if (ruid != 0 && setuid(0) == 0)
|
||||||
|
|
|
@ -1250,12 +1250,9 @@ static void __attribute__((__format__ (__printf__, 3, 4)))
|
||||||
}
|
}
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
|
|
||||||
if (geteuid() != getuid() || getegid() != getgid()) {
|
if ((geteuid() != getuid() || getegid() != getgid())
|
||||||
if (setgid(getgid()) < 0)
|
&& drop_permissions() != 0)
|
||||||
err(EXIT_FAILURE, _("setgid failed"));
|
err(EXIT_FAILURE, _("drop permissions failed"));
|
||||||
if (setuid(getuid()) < 0)
|
|
||||||
err(EXIT_FAILURE, _("setuid failed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
execvp(cmd, args);
|
execvp(cmd, args);
|
||||||
errsv = errno;
|
errsv = errno;
|
||||||
|
|
Loading…
Reference in New Issue