namespace-util: make "setgroups" users property writable via userns_acquire()
Unprivileged namespaces are only allowed if the "setgroups" file is set to "deny" for processes. And we need to write it before writing the gidmap. Hence add a parameter for that. Then, also patch all current users to actually enable this. The usecase generally don't need it (because they don't care about unprivileged userns), but it doesn't hurt to enable the concept anyway in all current users (none of them actually runs complex userspace in them, but they mostly use userns_acquire() for idmapped mounts and similar). Let's anyway make this option explicit in the function call, to indicate that the concept exists and is applied.
This commit is contained in:
@@ -524,8 +524,8 @@ int userns_acquire_empty(void) {
|
||||
return pidref_namespace_open_by_type(&pid, NAMESPACE_USER);
|
||||
}
|
||||
|
||||
int userns_acquire(const char *uid_map, const char *gid_map) {
|
||||
char path[STRLEN("/proc//uid_map") + DECIMAL_STR_MAX(pid_t) + 1];
|
||||
int userns_acquire(const char *uid_map, const char *gid_map, bool setgroups_deny) {
|
||||
char path[STRLEN("/proc//setgroups") + DECIMAL_STR_MAX(pid_t) + 1];
|
||||
_cleanup_(pidref_done_sigkill_wait) PidRef pid = PIDREF_NULL;
|
||||
int r;
|
||||
|
||||
@@ -546,6 +546,13 @@ int userns_acquire(const char *uid_map, const char *gid_map) {
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to write UID map: %m");
|
||||
|
||||
if (setgroups_deny) {
|
||||
xsprintf(path, "/proc/" PID_FMT "/setgroups", pid.pid);
|
||||
r = write_string_file(path, "deny", WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to write setgroups file: %m");
|
||||
}
|
||||
|
||||
xsprintf(path, "/proc/" PID_FMT "/gid_map", pid.pid);
|
||||
r = write_string_file(path, gid_map, WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||
if (r < 0)
|
||||
@@ -713,7 +720,7 @@ int is_idmapping_supported(const char *path) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
userns_fd = r = userns_acquire(uid_map, gid_map);
|
||||
userns_fd = r = userns_acquire(uid_map, gid_map, /* setgroups_deny= */ true);
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r) || r == -EINVAL)
|
||||
return false;
|
||||
if (r == -ENOSPC) {
|
||||
|
||||
@@ -86,7 +86,7 @@ static inline bool userns_shift_range_valid(uid_t shift, uid_t range) {
|
||||
int parse_userns_uid_range(const char *s, uid_t *ret_uid_shift, uid_t *ret_uid_range);
|
||||
|
||||
int userns_acquire_empty(void);
|
||||
int userns_acquire(const char *uid_map, const char *gid_map);
|
||||
int userns_acquire(const char *uid_map, const char *gid_map, bool setgroups_deny);
|
||||
int userns_enter_and_pin(int userns_fd, pid_t *ret_pid);
|
||||
|
||||
int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid);
|
||||
|
||||
@@ -1917,7 +1917,7 @@ static int apply_one_mount(
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
userns_fd = userns_acquire(uid_map, gid_map);
|
||||
userns_fd = userns_acquire(uid_map, gid_map, /* setgroups_deny= */ true);
|
||||
if (userns_fd < 0)
|
||||
return log_error_errno(userns_fd, "Failed to allocate user namespace: %m");
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ static int make_home_userns(uid_t stored_uid, uid_t exposed_uid) {
|
||||
|
||||
log_debug("Creating userns with mapping:\n%s", text);
|
||||
|
||||
userns_fd = userns_acquire(text, text); /* same uid + gid mapping */
|
||||
userns_fd = userns_acquire(text, text, /* setgroups_deny= */ true); /* same uid + gid mapping */
|
||||
if (userns_fd < 0)
|
||||
return log_error_errno(userns_fd, "Failed to allocate user namespace: %m");
|
||||
|
||||
|
||||
@@ -860,7 +860,7 @@ static int vl_method_mount_directory(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_close_ int idmap_userns_fd = userns_acquire(new_uid_map, new_uid_map);
|
||||
_cleanup_close_ int idmap_userns_fd = userns_acquire(new_uid_map, new_uid_map, /* setgroups_deny= */ true);
|
||||
if (idmap_userns_fd < 0)
|
||||
return log_debug_errno(idmap_userns_fd, "Failed to acquire user namespace for id mapping: %m");
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ static int run(int argc, char *argv[]) {
|
||||
host_tmpfs = make_tmpfs_fsmount();
|
||||
assert_se(host_tmpfs >= 0);
|
||||
|
||||
userns_fd = userns_acquire("0 0 1", "0 0 1");
|
||||
userns_fd = userns_acquire("0 0 1", "0 0 1", /* setgroups_deny= */ true);
|
||||
if (userns_fd < 0)
|
||||
return log_error_errno(userns_fd, "Failed to make user namespace: %m");
|
||||
|
||||
|
||||
@@ -1442,7 +1442,7 @@ int make_userns(uid_t uid_shift,
|
||||
}
|
||||
|
||||
/* We always assign the same UID and GID ranges */
|
||||
userns_fd = userns_acquire(line, line);
|
||||
userns_fd = userns_acquire(line, line, /* setgroups_deny= */ true);
|
||||
if (userns_fd < 0)
|
||||
return log_debug_errno(userns_fd, "Failed to acquire new userns: %m");
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@ TEST(namespace_is_init) {
|
||||
TEST(userns_get_base_uid) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
|
||||
fd = userns_acquire("0 1 1", "0 2 1");
|
||||
fd = userns_acquire("0 1 1", "0 2 1", /* setgroups_deny= */ true);
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(fd))
|
||||
return (void) log_tests_skipped("userns is not supported");
|
||||
if (ERRNO_IS_NEG_PRIVILEGE(fd))
|
||||
|
||||
Reference in New Issue
Block a user