mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
uid-range: optionally load outside view of UID range from uid_map procfs file
This commit is contained in:
@@ -204,7 +204,7 @@ int uid_map_read_one(FILE *f, uid_t *ret_base, uid_t *ret_shift, uid_t *ret_rang
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uid_range_load_userns(UIDRange **ret, const char *path) {
|
||||
int uid_range_load_userns(UIDRange **ret, const char *path, UIDRangeUsernsMode mode) {
|
||||
_cleanup_(uid_range_freep) UIDRange *range = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
@@ -216,9 +216,11 @@ int uid_range_load_userns(UIDRange **ret, const char *path) {
|
||||
* To simplify things this will modify the passed array in case of later failure. */
|
||||
|
||||
assert(ret);
|
||||
assert(mode >= 0);
|
||||
assert(mode < _UID_RANGE_USERNS_MODE_MAX);
|
||||
|
||||
if (!path)
|
||||
path = "/proc/self/uid_map";
|
||||
path = IN_SET(mode, UID_RANGE_USERNS_INSIDE, UID_RANGE_USERNS_OUTSIDE) ? "/proc/self/uid_map" : "/proc/self/gid_map";
|
||||
|
||||
f = fopen(path, "re");
|
||||
if (!f) {
|
||||
@@ -243,7 +245,11 @@ int uid_range_load_userns(UIDRange **ret, const char *path) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = uid_range_add_internal(&range, uid_base, uid_range, /* coalesce = */ false);
|
||||
r = uid_range_add_internal(
|
||||
&range,
|
||||
IN_SET(mode, UID_RANGE_USERNS_INSIDE, GID_RANGE_USERNS_INSIDE) ? uid_base : uid_shift,
|
||||
uid_range,
|
||||
/* coalesce = */ false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,15 @@ static inline bool uid_range_contains(const UIDRange *range, uid_t uid) {
|
||||
|
||||
int uid_map_read_one(FILE *f, uid_t *ret_base, uid_t *ret_shift, uid_t *ret_range);
|
||||
|
||||
int uid_range_load_userns(UIDRange **ret, const char *path);
|
||||
typedef enum UIDRangeUsernsMode {
|
||||
UID_RANGE_USERNS_INSIDE,
|
||||
UID_RANGE_USERNS_OUTSIDE,
|
||||
GID_RANGE_USERNS_INSIDE,
|
||||
GID_RANGE_USERNS_OUTSIDE,
|
||||
_UID_RANGE_USERNS_MODE_MAX,
|
||||
_UID_RANGE_USERNS_MODE_INVALID = -EINVAL,
|
||||
} UIDRangeUsernsMode;
|
||||
|
||||
int uid_range_load_userns(UIDRange **ret, const char *path, UIDRangeUsernsMode mode);
|
||||
|
||||
bool uid_range_overlaps(const UIDRange *range, uid_t start, uid_t nr);
|
||||
|
||||
@@ -4805,7 +4805,7 @@ static int short_uid_range(const char *path) {
|
||||
/* Taint systemd if we the UID range assigned to this environment doesn't at least cover 0…65534,
|
||||
* i.e. from root to nobody. */
|
||||
|
||||
r = uid_range_load_userns(&p, path);
|
||||
r = uid_range_load_userns(&p, path, UID_RANGE_USERNS_INSIDE);
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
|
||||
return false;
|
||||
if (r < 0)
|
||||
|
||||
@@ -473,7 +473,7 @@ static bool check_sender_uid(sd_device_monitor *m, uid_t uid) {
|
||||
return true;
|
||||
|
||||
if (!m->mapped_userns_uid_range) {
|
||||
r = uid_range_load_userns(&m->mapped_userns_uid_range, NULL);
|
||||
r = uid_range_load_userns(&m->mapped_userns_uid_range, NULL, UID_RANGE_USERNS_INSIDE);
|
||||
if (r < 0)
|
||||
log_monitor_errno(m, r, "Failed to load UID ranges mapped to the current user namespace, ignoring: %m");
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ TEST(load_userns) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
r = uid_range_load_userns(&p, NULL);
|
||||
r = uid_range_load_userns(&p, NULL, UID_RANGE_USERNS_INSIDE);
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
|
||||
return;
|
||||
|
||||
@@ -123,7 +123,7 @@ TEST(load_userns) {
|
||||
|
||||
p = uid_range_free(p);
|
||||
|
||||
assert_se(uid_range_load_userns(&p, fn) >= 0);
|
||||
assert_se(uid_range_load_userns(&p, fn, UID_RANGE_USERNS_INSIDE) >= 0);
|
||||
|
||||
assert_se(uid_range_contains(p, 0));
|
||||
assert_se(uid_range_contains(p, 19));
|
||||
|
||||
@@ -428,7 +428,7 @@ static int display_user(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(uid_range_freep) UIDRange *uid_range = NULL;
|
||||
int boundary_lines, uid_map_lines;
|
||||
|
||||
r = uid_range_load_userns(&uid_range, "/proc/self/uid_map");
|
||||
r = uid_range_load_userns(&uid_range, "/proc/self/uid_map", UID_RANGE_USERNS_INSIDE);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to load /proc/self/uid_map, ignoring: %m");
|
||||
|
||||
@@ -731,7 +731,7 @@ static int display_group(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(uid_range_freep) UIDRange *gid_range = NULL;
|
||||
int boundary_lines, gid_map_lines;
|
||||
|
||||
r = uid_range_load_userns(&gid_range, "/proc/self/gid_map");
|
||||
r = uid_range_load_userns(&gid_range, "/proc/self/gid_map", UID_RANGE_USERNS_INSIDE);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to load /proc/self/gid_map, ignoring: %m");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user