diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/basic/audit-util.c | 7 | ||||
| -rw-r--r-- | src/basic/capability-util.c | 3 | ||||
| -rw-r--r-- | src/basic/user-util.c | 27 | ||||
| -rw-r--r-- | src/basic/user-util.h | 2 | ||||
| -rw-r--r-- | src/core/execute.c | 2 | ||||
| -rw-r--r-- | src/core/umount.c | 2 | 
6 files changed, 37 insertions, 6 deletions
| diff --git a/src/basic/audit-util.c b/src/basic/audit-util.c index 5741fecdd6..d1c9695973 100644 --- a/src/basic/audit-util.c +++ b/src/basic/audit-util.c @@ -92,8 +92,11 @@ bool use_audit(void) {                  int fd;                  fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_AUDIT); -                if (fd < 0) -                        cached_use = errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT; +                if (fd < 0) { +                        cached_use = !IN_SET(errno, EAFNOSUPPORT, EPROTONOSUPPORT, EPERM); +                        if (errno == EPERM) +                                log_debug_errno(errno, "Audit access prohibited, won't talk to audit"); +                }                  else {                          cached_use = true;                          safe_close(fd); diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c index d4c5bd6937..f8db6e0212 100644 --- a/src/basic/capability-util.c +++ b/src/basic/capability-util.c @@ -31,6 +31,7 @@  #include "log.h"  #include "macro.h"  #include "parse-util.h" +#include "user-util.h"  #include "util.h"  int have_effective_cap(int value) { @@ -295,7 +296,7 @@ int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities) {          if (setresgid(gid, gid, gid) < 0)                  return log_error_errno(errno, "Failed to change group ID: %m"); -        if (setgroups(0, NULL) < 0) +        if (maybe_setgroups(0, NULL) < 0)                  return log_error_errno(errno, "Failed to drop auxiliary groups list: %m");          /* Ensure we keep the permitted caps across the setresuid() */ diff --git a/src/basic/user-util.c b/src/basic/user-util.c index 0522bce1d1..16496fccfa 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -33,6 +33,7 @@  #include "alloc-util.h"  #include "fd-util.h" +#include "fileio.h"  #include "formats-util.h"  #include "macro.h"  #include "missing.h" @@ -460,7 +461,7 @@ int get_shell(char **_s) {  int reset_uid_gid(void) { -        if (setgroups(0, NULL) < 0) +        if (maybe_setgroups(0, NULL) < 0)                  return -errno;          if (setresgid(0, 0, 0) < 0) @@ -602,3 +603,27 @@ bool valid_home(const char *p) {          return true;  } + +int maybe_setgroups(size_t size, const gid_t *list) { +        static int cached_can_setgroups = -1; +        /* check if setgroups is allowed before we try to drop all the auxiliary groups */ +        if (size == 0) { +                if (cached_can_setgroups < 0) { +                        _cleanup_free_ char *setgroups_content = NULL; +                        int r = read_one_line_file("/proc/self/setgroups", &setgroups_content); +                        if (r < 0 && errno != ENOENT) +                                return r; +                        if (r < 0) { +                                /* old kernels don't have /proc/self/setgroups, so assume we can use setgroups */ +                                cached_can_setgroups = true; +                        } else { +                                cached_can_setgroups = streq(setgroups_content, "allow"); +                                if (!cached_can_setgroups) +                                        log_debug("skip setgroups, /proc/self/setgroups is set to 'deny'"); +                        } +                } +                if (!cached_can_setgroups) +                        return 0; +        } +        return setgroups(size, list); +} diff --git a/src/basic/user-util.h b/src/basic/user-util.h index 6c61f63cae..dfea561bde 100644 --- a/src/basic/user-util.h +++ b/src/basic/user-util.h @@ -86,3 +86,5 @@ bool valid_user_group_name(const char *u);  bool valid_user_group_name_or_id(const char *u);  bool valid_gecos(const char *d);  bool valid_home(const char *p); + +int maybe_setgroups(size_t size, const gid_t *list); diff --git a/src/core/execute.c b/src/core/execute.c index 82d8c978c1..019ff8490b 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -781,7 +781,7 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_                          k++;                  } -                if (setgroups(k, gids) < 0) { +                if (maybe_setgroups(k, gids) < 0) {                          free(gids);                          return -errno;                  } diff --git a/src/core/umount.c b/src/core/umount.c index c21a2be54e..1e5459ed80 100644 --- a/src/core/umount.c +++ b/src/core/umount.c @@ -375,7 +375,7 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e                  /* If we are in a container, don't attempt to                     read-only mount anything as that brings no real                     benefits, but might confuse the host, as we remount -                   the superblock here, not the bind mound. */ +                   the superblock here, not the bind mount. */                  if (detect_container() <= 0)  {                          _cleanup_free_ char *options = NULL;                          /* MS_REMOUNT requires that the data parameter | 
