test: Gracefully handle running within user namespace with single user

Unprivileged users often make themselves root by unsharing a user namespace
and then mapping their current user to root which does not require privileges.
Let's make sure our tests don't fail in such an environment by adding checks
where required to see if we're not running in a user namespace with only a
single user.
This commit is contained in:
Daan De Meyer
2024-08-18 21:53:52 +02:00
parent d098b8df6e
commit ef31767ed7
10 changed files with 43 additions and 10 deletions
+19
View File
@@ -29,6 +29,7 @@
#include "strv.h"
#include "tests.h"
#include "tmpfile-util.h"
#include "uid-range.h"
char* setup_fake_runtime_dir(void) {
char t[] = "/tmp/fake-xdg-runtime-XXXXXX", *p;
@@ -166,6 +167,24 @@ bool have_namespaces(void) {
assert_not_reached();
}
bool userns_has_single_user(void) {
_cleanup_(uid_range_freep) UIDRange *uidrange = NULL, *gidrange = NULL;
/* Check if we're in a user namespace with only a single user mapped in. We special case this
* scenario in a few tests because it's the only kind of namespace that can be created unprivileged
* and as such happens more often than not, so we make sure to deal with it so that all tests pass
* in such environments. */
if (uid_range_load_userns(NULL, UID_RANGE_USERNS_INSIDE, &uidrange) < 0)
return false;
if (uid_range_load_userns(NULL, GID_RANGE_USERNS_INSIDE, &gidrange) < 0)
return false;
return uidrange->n_entries == 1 && uidrange->entries[0].nr == 1 &&
gidrange->n_entries == 1 && gidrange->entries[0].nr == 1;
}
bool can_memlock(void) {
/* Let's see if we can mlock() a larger blob of memory. BPF programs are charged against
* RLIMIT_MEMLOCK, hence let's first make sure we can lock memory at all, and skip the test if we
+1
View File
@@ -76,6 +76,7 @@ void test_setup_logging(int level);
int write_tmpfile(char *pattern, const char *contents);
bool have_namespaces(void);
bool userns_has_single_user(void);
/* We use the small but non-trivial limit here */
#define CAN_MEMLOCK_SIZE (512 * 1024U)