1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) Huawei Technologies Co., Ltd., 2015
4 * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
5 */
6
7 /*\
8 * [Description]
9 *
10 * Clone a process with CLONE_NEWPID flag and check for the maxium amount of
11 * nested containers.
12 */
13
14 #define _GNU_SOURCE
15 #include <sys/mman.h>
16 #include "tst_test.h"
17 #include "tst_atomic.h"
18 #include "lapi/sched.h"
19
20 #define MAXNEST 32
21
22 static const struct tst_clone_args args = {
23 .flags = CLONE_NEWPID,
24 .exit_signal = SIGCHLD,
25 };
26 static int *level;
27
child_func(void)28 static pid_t child_func(void)
29 {
30 pid_t cpid = 0;
31
32 if (tst_atomic_inc(level) == MAXNEST)
33 return cpid;
34
35 cpid = SAFE_CLONE(&args);
36 if (!cpid) {
37 child_func();
38 return cpid;
39 }
40
41 tst_reap_children();
42
43 return cpid;
44 }
45
setup(void)46 static void setup(void)
47 {
48 level = SAFE_MMAP(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
49 }
50
cleanup(void)51 static void cleanup(void)
52 {
53 SAFE_MUNMAP(level, sizeof(int));
54 }
55
run(void)56 static void run(void)
57 {
58 *level = 0;
59
60 if (!child_func())
61 return;
62
63 TST_EXP_EQ_LI(*level, MAXNEST);
64 }
65
66 static struct tst_test test = {
67 .test_all = run,
68 .needs_root = 1,
69 .setup = setup,
70 .cleanup = cleanup,
71 .forks_child = 1,
72 };
73