#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <sys/types.h>
+#include <grp.h>
#include <assert.h>
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
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;
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));
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;
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))
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))
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
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)
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) {
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)
}
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;