103 lines
2.0 KiB
C
103 lines
2.0 KiB
C
|
// SPDX-License-Identifier: GPL-2.0
|
||
|
#define _GNU_SOURCE
|
||
|
#include <test_progs.h>
|
||
|
#include "test_deny_namespace.skel.h"
|
||
|
#include <sched.h>
|
||
|
#include "cap_helpers.h"
|
||
|
#include <stdio.h>
|
||
|
|
||
|
static int wait_for_pid(pid_t pid)
|
||
|
{
|
||
|
int status, ret;
|
||
|
|
||
|
again:
|
||
|
ret = waitpid(pid, &status, 0);
|
||
|
if (ret == -1) {
|
||
|
if (errno == EINTR)
|
||
|
goto again;
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (!WIFEXITED(status))
|
||
|
return -1;
|
||
|
|
||
|
return WEXITSTATUS(status);
|
||
|
}
|
||
|
|
||
|
/* negative return value -> some internal error
|
||
|
* positive return value -> userns creation failed
|
||
|
* 0 -> userns creation succeeded
|
||
|
*/
|
||
|
static int create_user_ns(void)
|
||
|
{
|
||
|
pid_t pid;
|
||
|
|
||
|
pid = fork();
|
||
|
if (pid < 0)
|
||
|
return -1;
|
||
|
|
||
|
if (pid == 0) {
|
||
|
if (unshare(CLONE_NEWUSER))
|
||
|
_exit(EXIT_FAILURE);
|
||
|
_exit(EXIT_SUCCESS);
|
||
|
}
|
||
|
|
||
|
return wait_for_pid(pid);
|
||
|
}
|
||
|
|
||
|
static void test_userns_create_bpf(void)
|
||
|
{
|
||
|
__u32 cap_mask = 1ULL << CAP_SYS_ADMIN;
|
||
|
__u64 old_caps = 0;
|
||
|
|
||
|
cap_enable_effective(cap_mask, &old_caps);
|
||
|
|
||
|
ASSERT_OK(create_user_ns(), "priv new user ns");
|
||
|
|
||
|
cap_disable_effective(cap_mask, &old_caps);
|
||
|
|
||
|
ASSERT_EQ(create_user_ns(), EPERM, "unpriv new user ns");
|
||
|
|
||
|
if (cap_mask & old_caps)
|
||
|
cap_enable_effective(cap_mask, NULL);
|
||
|
}
|
||
|
|
||
|
static void test_unpriv_userns_create_no_bpf(void)
|
||
|
{
|
||
|
__u32 cap_mask = 1ULL << CAP_SYS_ADMIN;
|
||
|
__u64 old_caps = 0;
|
||
|
|
||
|
cap_disable_effective(cap_mask, &old_caps);
|
||
|
|
||
|
ASSERT_OK(create_user_ns(), "no-bpf unpriv new user ns");
|
||
|
|
||
|
if (cap_mask & old_caps)
|
||
|
cap_enable_effective(cap_mask, NULL);
|
||
|
}
|
||
|
|
||
|
void test_deny_namespace(void)
|
||
|
{
|
||
|
struct test_deny_namespace *skel = NULL;
|
||
|
int err;
|
||
|
|
||
|
if (test__start_subtest("unpriv_userns_create_no_bpf"))
|
||
|
test_unpriv_userns_create_no_bpf();
|
||
|
|
||
|
skel = test_deny_namespace__open_and_load();
|
||
|
if (!ASSERT_OK_PTR(skel, "skel load"))
|
||
|
goto close_prog;
|
||
|
|
||
|
err = test_deny_namespace__attach(skel);
|
||
|
if (!ASSERT_OK(err, "attach"))
|
||
|
goto close_prog;
|
||
|
|
||
|
if (test__start_subtest("userns_create_bpf"))
|
||
|
test_userns_create_bpf();
|
||
|
|
||
|
test_deny_namespace__detach(skel);
|
||
|
|
||
|
close_prog:
|
||
|
test_deny_namespace__destroy(skel);
|
||
|
}
|