mirror of
https://github.com/systemd/systemd.git
synced 2025-03-22 06:50:18 +03:00
uid-range: add new uid_range_load_userns() for loading /proc/self/uid_map
This commit is contained in:
parent
2e37ebdae9
commit
5674aa7a2c
@ -5,8 +5,13 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "format-util.h"
|
||||
#include "macro.h"
|
||||
#include "path-util.h"
|
||||
#include "sort-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "uid-range.h"
|
||||
#include "user-util.h"
|
||||
|
||||
@ -178,3 +183,47 @@ bool uid_range_contains(const UidRange *p, size_t n, uid_t uid) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int uid_range_load_userns(UidRange **p, size_t *n, const char *path) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
/* If 'path' is NULL loads the UID range of the userns namespace we run. Otherwise load the data from
|
||||
* the specified file (which can be either uid_map or gid_map, in case caller needs to deal with GID
|
||||
* maps).
|
||||
*
|
||||
* To simplify things this will modify the passed array in case of later failure. */
|
||||
|
||||
if (!path)
|
||||
path = "/proc/self/uid_map";
|
||||
|
||||
f = fopen(path, "re");
|
||||
if (!f) {
|
||||
r = -errno;
|
||||
|
||||
if (r == -ENOENT && path_startswith(path, "/proc/") && proc_mounted() > 0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
uid_t uid_base, uid_shift, uid_range;
|
||||
int k;
|
||||
|
||||
errno = 0;
|
||||
k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &uid_base, &uid_shift, &uid_range);
|
||||
if (k == EOF) {
|
||||
if (ferror(f))
|
||||
return errno_or_else(EIO);
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (k != 3)
|
||||
return -EBADMSG;
|
||||
|
||||
r = uid_range_add(p, n, uid_base, uid_range);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
@ -13,3 +13,5 @@ int uid_range_add_str(UidRange **p, size_t *n, const char *s);
|
||||
|
||||
int uid_range_next_lower(const UidRange *p, size_t n, uid_t *uid);
|
||||
bool uid_range_contains(const UidRange *p, size_t n, uid_t uid);
|
||||
|
||||
int uid_range_load_userns(UidRange **p, size_t *n, const char *path);
|
||||
|
@ -3,10 +3,16 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "tests.h"
|
||||
#include "tmpfile-util.h"
|
||||
#include "uid-range.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
#include "virt.h"
|
||||
|
||||
TEST(uid_range) {
|
||||
_cleanup_free_ UidRange *p = NULL;
|
||||
@ -72,4 +78,45 @@ TEST(uid_range) {
|
||||
assert_se(p[0].nr == 1983);
|
||||
}
|
||||
|
||||
TEST(load_userns) {
|
||||
_cleanup_(unlink_and_freep) char *fn = NULL;
|
||||
_cleanup_free_ UidRange *p = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
size_t n = 0;
|
||||
int r;
|
||||
|
||||
r = uid_range_load_userns(&p, &n, NULL);
|
||||
if (ERRNO_IS_NOT_SUPPORTED(r))
|
||||
return;
|
||||
|
||||
assert_se(r >= 0);
|
||||
assert_se(uid_range_contains(p, n, getuid()));
|
||||
|
||||
r = running_in_userns();
|
||||
if (r == 0) {
|
||||
assert_se(n == 1);
|
||||
assert_se(p[0].start == 0);
|
||||
assert_se(p[0].nr == UINT32_MAX);
|
||||
}
|
||||
|
||||
assert_se(fopen_temporary(NULL, &f, &fn) >= 0);
|
||||
fputs("0 0 20\n"
|
||||
"100 0 20\n", f);
|
||||
assert_se(fflush_and_check(f) >= 0);
|
||||
|
||||
p = mfree(p);
|
||||
n = 0;
|
||||
|
||||
assert_se(uid_range_load_userns(&p, &n, fn) >= 0);
|
||||
|
||||
assert_se(uid_range_contains(p, n, 0));
|
||||
assert_se(uid_range_contains(p, n, 19));
|
||||
assert_se(!uid_range_contains(p, n, 20));
|
||||
|
||||
assert_se(!uid_range_contains(p, n, 99));
|
||||
assert_se(uid_range_contains(p, n, 100));
|
||||
assert_se(uid_range_contains(p, n, 119));
|
||||
assert_se(!uid_range_contains(p, n, 120));
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_DEBUG);
|
||||
|
Loading…
x
Reference in New Issue
Block a user