mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
namespace-util: introduce userns_acquire_self_root()
This is a simple helper for creating a userns that just maps the callers user to UID 0 in the namespace. This can be acquired unpriv, which makes it useful for various purposes, for example for the logic in is_idmapping_supported(), hence port it over. (is_idmapping_supported() used a different mapping before, with the nobody users, but there's no real reason for that, and we'll use userns_acquire_self_root() elsewhere soon, where the root mapping is important).
This commit is contained in:
@@ -561,6 +561,21 @@ int userns_acquire(const char *uid_map, const char *gid_map, bool setgroups_deny
|
||||
return pidref_namespace_open_by_type(&pid, NAMESPACE_USER);
|
||||
}
|
||||
|
||||
int userns_acquire_self_root(void) {
|
||||
|
||||
/* Returns a user namespace with only our own uid/gid mapped to root, and everything else unmapped.
|
||||
*
|
||||
* Note: this can be acquired unprivileged! */
|
||||
|
||||
_cleanup_free_ char *uid_map = NULL, *gid_map = NULL;
|
||||
if (asprintf(&uid_map, "0 " UID_FMT " 1", getuid()) < 0)
|
||||
return -ENOMEM;
|
||||
if (asprintf(&gid_map, "0 " GID_FMT " 1", getgid()) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
return userns_acquire(uid_map, gid_map, /* setgroups_deny= */ true);
|
||||
}
|
||||
|
||||
int userns_enter_and_pin(int userns_fd, pid_t *ret_pid) {
|
||||
_cleanup_close_pair_ int pfd[2] = EBADF_PAIR;
|
||||
_cleanup_(sigkill_waitp) pid_t pid = 0;
|
||||
@@ -704,7 +719,6 @@ int process_is_owned_by_uid(const PidRef *pidref, uid_t uid) {
|
||||
|
||||
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);
|
||||
@@ -712,15 +726,7 @@ int is_idmapping_supported(const char *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, /* setgroups_deny= */ true);
|
||||
userns_fd = r = userns_acquire_self_root();
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r) || r == -EINVAL)
|
||||
return false;
|
||||
if (r == -ENOSPC) {
|
||||
|
||||
@@ -87,6 +87,7 @@ int parse_userns_uid_range(const char *s, uid_t *ret_uid_shift, uid_t *ret_uid_r
|
||||
|
||||
int userns_acquire_empty(void);
|
||||
int userns_acquire(const char *uid_map, const char *gid_map, bool setgroups_deny);
|
||||
int userns_acquire_self_root(void);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user