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