1 // SPDX-License-Identifier: GPL-2.0
2 #define _GNU_SOURCE
3 #include <test_progs.h>
4 #include "test_deny_namespace.skel.h"
5 #include <sched.h>
6 #include "cap_helpers.h"
7 #include <stdio.h>
8 
wait_for_pid(pid_t pid)9 static int wait_for_pid(pid_t pid)
10 {
11 	int status, ret;
12 
13 again:
14 	ret = waitpid(pid, &status, 0);
15 	if (ret == -1) {
16 		if (errno == EINTR)
17 			goto again;
18 
19 		return -1;
20 	}
21 
22 	if (!WIFEXITED(status))
23 		return -1;
24 
25 	return WEXITSTATUS(status);
26 }
27 
28 /* negative return value -> some internal error
29  * positive return value -> userns creation failed
30  * 0                     -> userns creation succeeded
31  */
create_user_ns(void)32 static int create_user_ns(void)
33 {
34 	pid_t pid;
35 
36 	pid = fork();
37 	if (pid < 0)
38 		return -1;
39 
40 	if (pid == 0) {
41 		if (unshare(CLONE_NEWUSER))
42 			_exit(EXIT_FAILURE);
43 		_exit(EXIT_SUCCESS);
44 	}
45 
46 	return wait_for_pid(pid);
47 }
48 
test_userns_create_bpf(void)49 static void test_userns_create_bpf(void)
50 {
51 	__u32 cap_mask = 1ULL << CAP_SYS_ADMIN;
52 	__u64 old_caps = 0;
53 
54 	cap_enable_effective(cap_mask, &old_caps);
55 
56 	ASSERT_OK(create_user_ns(), "priv new user ns");
57 
58 	cap_disable_effective(cap_mask, &old_caps);
59 
60 	ASSERT_EQ(create_user_ns(), EPERM, "unpriv new user ns");
61 
62 	if (cap_mask & old_caps)
63 		cap_enable_effective(cap_mask, NULL);
64 }
65 
test_unpriv_userns_create_no_bpf(void)66 static void test_unpriv_userns_create_no_bpf(void)
67 {
68 	__u32 cap_mask = 1ULL << CAP_SYS_ADMIN;
69 	__u64 old_caps = 0;
70 
71 	cap_disable_effective(cap_mask, &old_caps);
72 
73 	ASSERT_OK(create_user_ns(), "no-bpf unpriv new user ns");
74 
75 	if (cap_mask & old_caps)
76 		cap_enable_effective(cap_mask, NULL);
77 }
78 
test_deny_namespace(void)79 void test_deny_namespace(void)
80 {
81 	struct test_deny_namespace *skel = NULL;
82 	int err;
83 
84 	if (test__start_subtest("unpriv_userns_create_no_bpf"))
85 		test_unpriv_userns_create_no_bpf();
86 
87 	skel = test_deny_namespace__open_and_load();
88 	if (!ASSERT_OK_PTR(skel, "skel load"))
89 		goto close_prog;
90 
91 	err = test_deny_namespace__attach(skel);
92 	if (!ASSERT_OK(err, "attach"))
93 		goto close_prog;
94 
95 	if (test__start_subtest("userns_create_bpf"))
96 		test_userns_create_bpf();
97 
98 	test_deny_namespace__detach(skel);
99 
100 close_prog:
101 	test_deny_namespace__destroy(skel);
102 }
103