summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2025-01-15 06:10:21 +0100
committerGitHub <noreply@github.com>2025-01-15 06:10:21 +0100
commit132a164d974e01558f44de3901f436feec3cc652 (patch)
tree2417d5468ce456d0636b412335303176e1a4cbfa
parentconfidential-virt: add detection for aarch64 CCA (diff)
parentnamespace-util: use pidref_namespace_open_by_type() where appropriate (diff)
downloadsystemd-132a164d974e01558f44de3901f436feec3cc652.tar.xz
systemd-132a164d974e01558f44de3901f436feec3cc652.zip
Follow-ups for recent namespace PRs (#35923)
-rw-r--r--README1
-rw-r--r--src/basic/missing_fs.h23
-rw-r--r--src/basic/missing_namespace.h15
-rw-r--r--src/basic/namespace-util.c255
-rw-r--r--src/basic/namespace-util.h11
-rw-r--r--src/basic/process-util.c3
-rw-r--r--src/basic/uid-range.c49
-rw-r--r--src/basic/uid-range.h4
8 files changed, 157 insertions, 204 deletions
diff --git a/README b/README
index 75072382d1..3aba52921a 100644
--- a/README
+++ b/README
@@ -58,6 +58,7 @@ REQUIREMENTS:
Linux kernel ≥ 5.8 for LOOP_CONFIGURE and STATX_ATTR_MOUNT_ROOT
≥ 5.9 for close_range()
+ ≥ 5.12 for idmapped mount
≥ 5.14 for cgroup.kill
≥ 6.3 for MFD_EXEC/MFD_NOEXEC_SEAL and tmpfs noswap option
≥ 6.5 for name_to_handle_at() AT_HANDLE_FID, SO_PEERPIDFD/SO_PASSPIDFD,
diff --git a/src/basic/missing_fs.h b/src/basic/missing_fs.h
index ed6bdf0426..60b0a3a2a7 100644
--- a/src/basic/missing_fs.h
+++ b/src/basic/missing_fs.h
@@ -89,30 +89,17 @@ assert_cc(MS_STRICTATIME == (1 << 24));
assert_cc(MS_LAZYTIME == (1<<25));
#endif
-/* Not exposed yet. Defined at fs/ext4/ext4.h */
-#ifndef EXT4_IOC_RESIZE_FS
-#define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64)
-#endif
-
-/* linux/nsfs.h */
-#ifndef NS_GET_USERNS /* 6786741dbf99e44fb0c0ed85a37582b8a26f1c3b (4.9) */
-#define NS_GET_USERNS _IO(0xb7, 0x1)
-#endif
-
-#ifndef NS_GET_NSTYPE /* e5ff5ce6e20ee22511398bb31fb912466cf82a36 (4.11) */
-#define NS_GET_NSTYPE _IO(0xb7, 0x3)
-#endif
-
-#ifndef NS_GET_OWNER_UID /* d95fa3c76a66b6d76b1e109ea505c55e66360f3c (4.11) */
-#define NS_GET_OWNER_UID _IO(0xb7, 0x4)
-#endif
-
#ifndef FS_PROJINHERIT_FL
# define FS_PROJINHERIT_FL 0x20000000
#else
assert_cc(FS_PROJINHERIT_FL == 0x20000000);
#endif
+/* Not exposed yet. Defined at fs/ext4/ext4.h */
+#ifndef EXT4_IOC_RESIZE_FS
+#define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64)
+#endif
+
/* linux/fscrypt.h */
#ifndef FS_KEY_DESCRIPTOR_SIZE
# define FS_KEY_DESCRIPTOR_SIZE 8
diff --git a/src/basic/missing_namespace.h b/src/basic/missing_namespace.h
index 318c0143b8..1c7285151e 100644
--- a/src/basic/missing_namespace.h
+++ b/src/basic/missing_namespace.h
@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <linux/types.h>
+
/* Root namespace inode numbers, as per include/linux/proc_ns.h in the kernel source tree, since v3.8:
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=98f842e675f96ffac96e6c50315790912b2812be */
@@ -10,3 +12,16 @@
#define PROC_PID_INIT_INO ((ino_t) UINT32_C(0xEFFFFFFC))
#define PROC_CGROUP_INIT_INO ((ino_t) UINT32_C(0xEFFFFFFB))
#define PROC_TIME_INIT_INO ((ino_t) UINT32_C(0xEFFFFFFA))
+
+/* linux/nsfs.h */
+#ifndef NS_GET_USERNS /* 6786741dbf99e44fb0c0ed85a37582b8a26f1c3b (4.9) */
+#define NS_GET_USERNS _IO(0xb7, 0x1)
+#endif
+
+#ifndef NS_GET_NSTYPE /* e5ff5ce6e20ee22511398bb31fb912466cf82a36 (4.11) */
+#define NS_GET_NSTYPE _IO(0xb7, 0x3)
+#endif
+
+#ifndef NS_GET_OWNER_UID /* d95fa3c76a66b6d76b1e109ea505c55e66360f3c (4.11) */
+#define NS_GET_OWNER_UID _IO(0xb7, 0x4)
+#endif
diff --git a/src/basic/namespace-util.c b/src/basic/namespace-util.c
index da6ef37493..060c540f8a 100644
--- a/src/basic/namespace-util.c
+++ b/src/basic/namespace-util.c
@@ -474,94 +474,6 @@ int detach_mount_namespace_userns(int userns_fd) {
return detach_mount_namespace();
}
-int userns_acquire_empty(void) {
- _cleanup_(sigkill_waitp) pid_t pid = 0;
- _cleanup_close_ int userns_fd = -EBADF;
- int r;
-
- r = safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_USERNS, &pid);
- if (r < 0)
- return r;
- if (r == 0)
- /* Child. We do nothing here, just freeze until somebody kills us. */
- freeze();
-
- r = namespace_open(pid, NULL, NULL, NULL, &userns_fd, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to open userns fd: %m");
-
- return TAKE_FD(userns_fd);
-}
-
-int userns_acquire(const char *uid_map, const char *gid_map) {
- char path[STRLEN("/proc//uid_map") + DECIMAL_STR_MAX(pid_t) + 1];
- _cleanup_(sigkill_waitp) pid_t pid = 0;
- _cleanup_close_ int userns_fd = -EBADF;
- int r;
-
- assert(uid_map);
- assert(gid_map);
-
- /* Forks off a process in a new userns, configures the specified uidmap/gidmap, acquires an fd to it,
- * and then kills the process again. This way we have a userns fd that is not bound to any
- * process. We can use that for file system mounts and similar. */
-
- r = safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_USERNS, &pid);
- if (r < 0)
- return r;
- if (r == 0)
- /* Child. We do nothing here, just freeze until somebody kills us. */
- freeze();
-
- xsprintf(path, "/proc/" PID_FMT "/uid_map", pid);
- r = write_string_file(path, uid_map, WRITE_STRING_FILE_DISABLE_BUFFER);
- if (r < 0)
- return log_debug_errno(r, "Failed to write UID map: %m");
-
- xsprintf(path, "/proc/" PID_FMT "/gid_map", pid);
- r = write_string_file(path, gid_map, WRITE_STRING_FILE_DISABLE_BUFFER);
- if (r < 0)
- return log_debug_errno(r, "Failed to write GID map: %m");
-
- r = namespace_open(pid,
- /* ret_pidns_fd = */ NULL,
- /* ret_mntns_fd = */ NULL,
- /* ret_netns_fd = */ NULL,
- &userns_fd,
- /* ret_root_fd = */ NULL);
- if (r < 0)
- return log_debug_errno(r, "Failed to open userns fd: %m");
-
- return TAKE_FD(userns_fd);
-}
-
-int netns_acquire(void) {
- _cleanup_(sigkill_waitp) pid_t pid = 0;
- _cleanup_close_ int netns_fd = -EBADF;
- int r;
-
- /* Forks off a process in a new network namespace, acquires a network namespace fd, and then kills
- * the process again. This way we have a netns fd that is not bound to any process. */
-
- r = safe_fork("(sd-mknetns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_NETNS, &pid);
- if (r < 0)
- return log_debug_errno(r, "Failed to fork process (sd-mknetns): %m");
- if (r == 0)
- /* Child. We do nothing here, just freeze until somebody kills us. */
- freeze();
-
- r = namespace_open(pid,
- /* ret_pidns_fd = */ NULL,
- /* ret_mntns_fd = */ NULL,
- &netns_fd,
- /* ret_userns_fd = */ NULL,
- /* ret_root_fd = */ NULL);
- if (r < 0)
- return log_debug_errno(r, "Failed to open netns fd: %m");
-
- return TAKE_FD(netns_fd);
-}
-
int parse_userns_uid_range(const char *s, uid_t *ret_uid_shift, uid_t *ret_uid_range) {
_cleanup_free_ char *buffer = NULL;
const char *range, *shift;
@@ -600,60 +512,53 @@ int parse_userns_uid_range(const char *s, uid_t *ret_uid_shift, uid_t *ret_uid_r
return 0;
}
-int is_idmapping_supported(const char *path) {
- _cleanup_close_ int mount_fd = -EBADF, userns_fd = -EBADF, dir_fd = -EBADF;
- _cleanup_free_ char *uid_map = NULL, *gid_map = NULL;
+int userns_acquire_empty(void) {
+ _cleanup_(pidref_done_sigkill_wait) PidRef pid = PIDREF_NULL;
int r;
- assert(path);
-
- if (!mount_new_api_supported())
- return false;
-
- r = strextendf(&uid_map, UID_FMT " " UID_FMT " " UID_FMT "\n", UID_NOBODY, UID_NOBODY, 1u);
+ r = pidref_safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_USERNS, &pid);
if (r < 0)
return r;
+ if (r == 0)
+ /* Child. We do nothing here, just freeze until somebody kills us. */
+ freeze();
- r = strextendf(&gid_map, GID_FMT " " GID_FMT " " GID_FMT "\n", GID_NOBODY, GID_NOBODY, 1u);
- if (r < 0)
- return r;
+ return pidref_namespace_open_by_type(&pid, NAMESPACE_USER);
+}
- userns_fd = r = userns_acquire(uid_map, gid_map);
- if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r) || r == -EINVAL)
- return false;
- if (r == -ENOSPC) {
- log_debug_errno(r, "Failed to acquire new user namespace, user.max_user_namespaces seems to be exhausted or maybe even zero, assuming ID-mapping is not supported: %m");
- return false;
- }
- if (r < 0)
- return log_debug_errno(r, "Failed to acquire new user namespace for checking if '%s' supports ID-mapping: %m", path);
+int userns_acquire(const char *uid_map, const char *gid_map) {
+ char path[STRLEN("/proc//uid_map") + DECIMAL_STR_MAX(pid_t) + 1];
+ _cleanup_(pidref_done_sigkill_wait) PidRef pid = PIDREF_NULL;
+ int r;
- dir_fd = r = RET_NERRNO(open(path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
- if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
- return false;
+ assert(uid_map);
+ assert(gid_map);
+
+ /* Forks off a process in a new userns, configures the specified uidmap/gidmap, acquires an fd to it,
+ * and then kills the process again. This way we have a userns fd that is not bound to any
+ * process. We can use that for file system mounts and similar. */
+
+ r = pidref_safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_USERNS, &pid);
if (r < 0)
- return log_debug_errno(r, "Failed to open '%s', cannot determine if ID-mapping is supported: %m", path);
+ return r;
+ if (r == 0)
+ /* Child. We do nothing here, just freeze until somebody kills us. */
+ freeze();
- mount_fd = r = RET_NERRNO(open_tree(dir_fd, "", AT_EMPTY_PATH | OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC));
- if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r) || r == -EINVAL)
- return false;
+ xsprintf(path, "/proc/" PID_FMT "/uid_map", pid.pid);
+ r = write_string_file(path, uid_map, WRITE_STRING_FILE_DISABLE_BUFFER);
if (r < 0)
- return log_debug_errno(r, "Failed to open mount tree '%s', cannot determine if ID-mapping is supported: %m", path);
+ return log_debug_errno(r, "Failed to write UID map: %m");
- r = RET_NERRNO(mount_setattr(mount_fd, "", AT_EMPTY_PATH,
- &(struct mount_attr) {
- .attr_set = MOUNT_ATTR_IDMAP | MOUNT_ATTR_NOSUID | MOUNT_ATTR_NOEXEC | MOUNT_ATTR_RDONLY | MOUNT_ATTR_NODEV,
- .userns_fd = userns_fd,
- }, sizeof(struct mount_attr)));
- if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r) || r == -EINVAL)
- return false;
+ xsprintf(path, "/proc/" PID_FMT "/gid_map", pid.pid);
+ r = write_string_file(path, gid_map, WRITE_STRING_FILE_DISABLE_BUFFER);
if (r < 0)
- return log_debug_errno(r, "Failed to set mount attribute to '%s', cannot determine if ID-mapping is supported: %m", path);
+ return log_debug_errno(r, "Failed to write GID map: %m");
- return true;
+ return pidref_namespace_open_by_type(&pid, NAMESPACE_USER);
}
-int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid) {
+int userns_enter_and_pin(int userns_fd, pid_t *ret_pid) {
_cleanup_(close_pairp) int pfd[2] = EBADF_PAIR;
_cleanup_(sigkill_waitp) pid_t pid = 0;
ssize_t n;
@@ -661,12 +566,13 @@ int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid) {
int r;
assert(userns_fd >= 0);
+ assert(ret_pid);
if (pipe2(pfd, O_CLOEXEC) < 0)
return -errno;
r = safe_fork_full(
- "(sd-baseuns)",
+ "(sd-pinuserns)",
/* stdio_fds= */ NULL,
(int[]) { pfd[1], userns_fd }, 2,
FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL,
@@ -703,13 +609,27 @@ int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid) {
assert(n == 1);
assert(x == 'x');
+ *ret_pid = TAKE_PID(pid);
+ return 0;
+}
+
+int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid) {
+ _cleanup_(sigkill_waitp) pid_t pid = 0;
+ int r;
+
+ assert(userns_fd >= 0);
+
+ r = userns_enter_and_pin(userns_fd, &pid);
+ if (r < 0)
+ return r;
+
uid_t uid;
- r = uid_map_search_root(pid, "uid_map", &uid);
+ r = uid_map_search_root(pid, UID_RANGE_USERNS_OUTSIDE, &uid);
if (r < 0)
return r;
gid_t gid;
- r = uid_map_search_root(pid, "gid_map", &gid);
+ r = uid_map_search_root(pid, GID_RANGE_USERNS_OUTSIDE, &gid);
if (r < 0)
return r;
@@ -725,13 +645,13 @@ int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid) {
}
int process_is_owned_by_uid(const PidRef *pidref, uid_t uid) {
- assert(uid_is_valid(uid));
-
int r;
/* Checks if the specified process either is owned directly by the specified user, or if it is inside
* a user namespace owned by it. */
+ assert(uid_is_valid(uid));
+
uid_t process_uid;
r = pidref_get_uid(pidref, &process_uid);
if (r < 0)
@@ -778,3 +698,74 @@ int process_is_owned_by_uid(const PidRef *pidref, uid_t uid) {
close_and_replace(userns_fd, parent_fd);
}
}
+
+int is_idmapping_supported(const char *path) {
+ _cleanup_close_ int mount_fd = -EBADF, userns_fd = -EBADF, dir_fd = -EBADF;
+ _cleanup_free_ char *uid_map = NULL, *gid_map = NULL;
+ int r;
+
+ assert(path);
+
+ if (!mount_new_api_supported())
+ return false;
+
+ r = strextendf(&uid_map, UID_FMT " " UID_FMT " " UID_FMT "\n", UID_NOBODY, UID_NOBODY, 1u);
+ if (r < 0)
+ return r;
+
+ r = strextendf(&gid_map, GID_FMT " " GID_FMT " " GID_FMT "\n", GID_NOBODY, GID_NOBODY, 1u);
+ if (r < 0)
+ return r;
+
+ userns_fd = r = userns_acquire(uid_map, gid_map);
+ if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r) || r == -EINVAL)
+ return false;
+ if (r == -ENOSPC) {
+ log_debug_errno(r, "Failed to acquire new user namespace, user.max_user_namespaces seems to be exhausted or maybe even zero, assuming ID-mapping is not supported: %m");
+ return false;
+ }
+ if (r < 0)
+ return log_debug_errno(r, "Failed to acquire new user namespace for checking if '%s' supports ID-mapping: %m", path);
+
+ dir_fd = r = RET_NERRNO(open(path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
+ if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
+ return false;
+ if (r < 0)
+ return log_debug_errno(r, "Failed to open '%s', cannot determine if ID-mapping is supported: %m", path);
+
+ mount_fd = r = RET_NERRNO(open_tree(dir_fd, "", AT_EMPTY_PATH | OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC));
+ if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r) || r == -EINVAL)
+ return false;
+ if (r < 0)
+ return log_debug_errno(r, "Failed to open mount tree '%s', cannot determine if ID-mapping is supported: %m", path);
+
+ r = RET_NERRNO(mount_setattr(mount_fd, "", AT_EMPTY_PATH,
+ &(struct mount_attr) {
+ .attr_set = MOUNT_ATTR_IDMAP | MOUNT_ATTR_NOSUID | MOUNT_ATTR_NOEXEC | MOUNT_ATTR_RDONLY | MOUNT_ATTR_NODEV,
+ .userns_fd = userns_fd,
+ }, sizeof(struct mount_attr)));
+ if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r) || r == -EINVAL)
+ return false;
+ if (r < 0)
+ return log_debug_errno(r, "Failed to set mount attribute to '%s', cannot determine if ID-mapping is supported: %m", path);
+
+ return true;
+}
+
+int netns_acquire(void) {
+ _cleanup_(pidref_done_sigkill_wait) PidRef pid = PIDREF_NULL;
+ int r;
+
+ /* Forks off a process in a new network namespace, acquires a network namespace fd, and then kills
+ * the process again. This way we have a netns fd that is not bound to any process. */
+
+ r = pidref_safe_fork("(sd-mknetns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_NETNS, &pid);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to fork process into new netns: %m");
+ if (r == 0)
+ /* Child. We do nothing here, just freeze until somebody kills us. */
+ freeze();
+
+ return pidref_namespace_open_by_type(&pid, NAMESPACE_NET);
+}
+
diff --git a/src/basic/namespace-util.h b/src/basic/namespace-util.h
index ea2488a432..3d40a515e7 100644
--- a/src/basic/namespace-util.h
+++ b/src/basic/namespace-util.h
@@ -83,15 +83,16 @@ static inline bool userns_shift_range_valid(uid_t shift, uid_t range) {
return true;
}
+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_enter_and_pin(int userns_fd, pid_t *ret_pid);
-int netns_acquire(void);
+int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid);
-int parse_userns_uid_range(const char *s, uid_t *ret_uid_shift, uid_t *ret_uid_range);
+int process_is_owned_by_uid(const PidRef *pidref, uid_t uid);
int is_idmapping_supported(const char *path);
-int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid);
-
-int process_is_owned_by_uid(const PidRef *pidref, uid_t uid);
+int netns_acquire(void);
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 59c0fdd0f9..a13e2d5f28 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -1542,9 +1542,6 @@ int safe_fork_full(
}
if (FLAGS_SET(flags, FORK_DETACH)) {
- assert(!FLAGS_SET(flags, FORK_WAIT));
- assert(!ret_pid);
-
/* Fork off intermediary child if needed */
r = is_reaper_process();
diff --git a/src/basic/uid-range.c b/src/basic/uid-range.c
index 687ddacc57..99984d8a4e 100644
--- a/src/basic/uid-range.c
+++ b/src/basic/uid-range.c
@@ -9,6 +9,7 @@
#include "fd-util.h"
#include "format-util.h"
#include "macro.h"
+#include "namespace-util.h"
#include "path-util.h"
#include "process-util.h"
#include "sort-util.h"
@@ -264,10 +265,7 @@ int uid_range_load_userns(const char *path, UIDRangeUsernsMode mode, UIDRange **
}
int uid_range_load_userns_by_fd(int userns_fd, UIDRangeUsernsMode mode, UIDRange **ret) {
- _cleanup_(close_pairp) int pfd[2] = EBADF_PAIR;
_cleanup_(sigkill_waitp) pid_t pid = 0;
- ssize_t n;
- char x;
int r;
assert(userns_fd >= 0);
@@ -275,46 +273,9 @@ int uid_range_load_userns_by_fd(int userns_fd, UIDRangeUsernsMode mode, UIDRange
assert(mode < _UID_RANGE_USERNS_MODE_MAX);
assert(ret);
- if (pipe2(pfd, O_CLOEXEC) < 0)
- return -errno;
-
- r = safe_fork_full(
- "(sd-mkuserns)",
- /* stdio_fds= */ NULL,
- (int[]) { pfd[1], userns_fd }, 2,
- FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL,
- &pid);
+ r = userns_enter_and_pin(userns_fd, &pid);
if (r < 0)
return r;
- if (r == 0) {
- /* Child. */
-
- if (setns(userns_fd, CLONE_NEWUSER) < 0) {
- log_debug_errno(errno, "Failed to join userns: %m");
- _exit(EXIT_FAILURE);
- }
-
- userns_fd = safe_close(userns_fd);
-
- n = write(pfd[1], &(const char) { 'x' }, 1);
- if (n < 0) {
- log_debug_errno(errno, "Failed to write to fifo: %m");
- _exit(EXIT_FAILURE);
- }
- assert(n == 1);
-
- freeze();
- }
-
- pfd[1] = safe_close(pfd[1]);
-
- n = read(pfd[0], &x, 1);
- if (n < 0)
- return -errno;
- if (n == 0)
- return -EPROTO;
- assert(n == 1);
- assert(x == 'x');
const char *p = procfs_file_alloca(
pid,
@@ -363,13 +324,13 @@ bool uid_range_equal(const UIDRange *a, const UIDRange *b) {
return true;
}
-int uid_map_search_root(pid_t pid, const char *filename, uid_t *ret) {
+int uid_map_search_root(pid_t pid, UIDRangeUsernsMode mode, uid_t *ret) {
int r;
assert(pid_is_valid(pid));
- assert(filename);
+ assert(IN_SET(mode, UID_RANGE_USERNS_OUTSIDE, GID_RANGE_USERNS_OUTSIDE));
- const char *p = procfs_file_alloca(pid, filename);
+ const char *p = procfs_file_alloca(pid, mode == UID_RANGE_USERNS_OUTSIDE ? "uid_map" : "gid_map");
_cleanup_fclose_ FILE *f = fopen(p, "re");
if (!f) {
if (errno != ENOENT)
diff --git a/src/basic/uid-range.h b/src/basic/uid-range.h
index 41ca671dd6..21e5c7a17b 100644
--- a/src/basic/uid-range.h
+++ b/src/basic/uid-range.h
@@ -15,7 +15,7 @@ typedef struct UIDRange {
size_t n_entries;
} UIDRange;
-UIDRange *uid_range_free(UIDRange *range);
+UIDRange* uid_range_free(UIDRange *range);
DEFINE_TRIVIAL_CLEANUP_FUNC(UIDRange*, uid_range_free);
int uid_range_add_internal(UIDRange **range, uid_t start, uid_t nr, bool coalesce);
@@ -77,4 +77,4 @@ int uid_range_load_userns_by_fd(int userns_fd, UIDRangeUsernsMode mode, UIDRange
bool uid_range_overlaps(const UIDRange *range, uid_t start, uid_t nr);
-int uid_map_search_root(pid_t pid, const char *filename, uid_t *ret);
+int uid_map_search_root(pid_t pid, UIDRangeUsernsMode mode, uid_t *ret);