xref: /aosp_15_r20/external/ltp/testcases/kernel/containers/userns/userns04.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) Huawei Technologies Co., Ltd., 2015
4  * Copyright (C) 2022 SUSE LLC Andrea Cervesato <[email protected]>
5  */
6 
7 /*\
8  * [Description]
9  *
10  * Verify that if a namespace isn't another namespace's ancestor, the process in
11  * first namespace does not have the CAP_SYS_ADMIN capability in the second
12  * namespace and the setns() call fails.
13  */
14 
15 #define _GNU_SOURCE
16 
17 #include <stdio.h>
18 #include "tst_test.h"
19 #include "lapi/sched.h"
20 
child_fn1(void)21 static void child_fn1(void)
22 {
23 	TST_CHECKPOINT_WAIT(0);
24 }
25 
child_fn2(int fd)26 static void child_fn2(int fd)
27 {
28 	TST_EXP_FAIL(setns(fd, CLONE_NEWUSER), EPERM);
29 	TST_CHECKPOINT_WAIT(1);
30 }
31 
run(void)32 static void run(void)
33 {
34 	const struct tst_clone_args args = {
35 		.flags = CLONE_NEWUSER,
36 		.exit_signal = SIGCHLD,
37 	};
38 	pid_t cpid1, cpid2, cpid3;
39 	char path[BUFSIZ];
40 	int fd;
41 
42 	cpid1 = SAFE_CLONE(&args);
43 	if (!cpid1) {
44 		child_fn1();
45 		return;
46 	}
47 
48 	sprintf(path, "/proc/%d/ns/user", cpid1);
49 
50 	fd = SAFE_OPEN(path, O_RDONLY, 0644);
51 
52 	cpid2 = SAFE_CLONE(&args);
53 	if (!cpid2) {
54 		child_fn2(fd);
55 		return;
56 	}
57 
58 	cpid3 = SAFE_FORK();
59 	if (!cpid3) {
60 		TST_EXP_PASS(setns(fd, CLONE_NEWUSER));
61 		return;
62 	}
63 
64 	TST_CHECKPOINT_WAKE(0);
65 	TST_CHECKPOINT_WAKE(1);
66 
67 	SAFE_CLOSE(fd);
68 }
69 
70 static struct tst_test test = {
71 	.test_all = run,
72 	.needs_root = 1,
73 	.forks_child = 1,
74 	.needs_checkpoints = 1,
75 	.needs_kconfigs = (const char *[]) {
76 		"CONFIG_USER_NS",
77 		NULL,
78 	},
79 };
80