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;
* 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) {
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;
}
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);
/* 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)
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");
}
_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;
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));
_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");
_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");