1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #define _GNU_SOURCE 3 #include <assert.h> 4 #include <errno.h> 5 #include <fcntl.h> 6 #include <linux/types.h> 7 #include <sched.h> 8 #include <signal.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <syscall.h> 13 #include <sys/wait.h> 14 15 #include "../kselftest_harness.h" 16 #include "../pidfd/pidfd.h" 17 18 #define __STACK_SIZE (8 * 1024 * 1024) 19 static pid_t do_clone(int (*fn)(void *), void *arg, int flags) 20 { 21 char *stack; 22 pid_t ret; 23 24 stack = malloc(__STACK_SIZE); 25 if (!stack) 26 return -ENOMEM; 27 28 #ifdef __ia64__ 29 ret = __clone2(fn, stack, __STACK_SIZE, flags | SIGCHLD, arg); 30 #else 31 ret = clone(fn, stack + __STACK_SIZE, flags | SIGCHLD, arg); 32 #endif 33 free(stack); 34 return ret; 35 } 36 37 static int pid_max_cb(void *data) 38 { 39 int fd, ret; 40 pid_t pid; 41 42 ret = mount("", "/", NULL, MS_PRIVATE | MS_REC, 0); 43 if (ret) { 44 fprintf(stderr, "%m - Failed to make rootfs private mount\n"); 45 return -1; 46 } 47 48 umount2("/proc", MNT_DETACH); 49 50 ret = mount("proc", "/proc", "proc", 0, NULL); 51 if (ret) { 52 fprintf(stderr, "%m - Failed to mount proc\n"); 53 return -1; 54 } 55 56 fd = open("/proc/sys/kernel/pid_max", O_RDWR | O_CLOEXEC | O_NOCTTY); 57 if (fd < 0) { 58 fprintf(stderr, "%m - Failed to open pid_max\n"); 59 return -1; 60 } 61 62 ret = write(fd, "500", sizeof("500") - 1); 63 if (ret < 0) { 64 fprintf(stderr, "%m - Failed to write pid_max\n"); 65 return -1; 66 } 67 68 for (int i = 0; i < 501; i++) { 69 pid = fork(); 70 if (pid == 0) 71 exit(EXIT_SUCCESS); 72 wait_for_pid(pid); 73 if (pid > 500) { 74 fprintf(stderr, "Managed to create pid number beyond limit\n"); 75 return -1; 76 } 77 } 78 79 return 0; 80 } 81 82 static int pid_max_nested_inner(void *data) 83 { 84 int fret = -1; 85 pid_t pids[2]; 86 int fd, i, ret; 87 88 ret = mount("", "/", NULL, MS_PRIVATE | MS_REC, 0); 89 if (ret) { 90 fprintf(stderr, "%m - Failed to make rootfs private mount\n"); 91 return fret; 92 } 93 94 umount2("/proc", MNT_DETACH); 95 96 ret = mount("proc", "/proc", "proc", 0, NULL); 97 if (ret) { 98 fprintf(stderr, "%m - Failed to mount proc\n"); 99 return fret; 100 } 101 102 fd = open("/proc/sys/kernel/pid_max", O_RDWR | O_CLOEXEC | O_NOCTTY); 103 if (fd < 0) { 104 fprintf(stderr, "%m - Failed to open pid_max\n"); 105 return fret; 106 } 107 108 ret = write(fd, "500", sizeof("500") - 1); 109 close(fd); 110 if (ret < 0) { 111 fprintf(stderr, "%m - Failed to write pid_max\n"); 112 return fret; 113 } 114 115 pids[0] = fork(); 116 if (pids[0] < 0) { 117 fprintf(stderr, "Failed to create first new process\n"); 118 return fret; 119 } 120 121 if (pids[0] == 0) 122 exit(EXIT_SUCCESS); 123 124 pids[1] = fork(); 125 wait_for_pid(pids[0]); 126 if (pids[1] >= 0) { 127 if (pids[1] == 0) 128 exit(EXIT_SUCCESS); 129 wait_for_pid(pids[1]); 130 131 fprintf(stderr, "Managed to create process even though ancestor pid namespace had a limit\n"); 132 return fret; 133 } 134 135 /* Now make sure that we wrap pids at 400. */ 136 for (i = 0; i < 510; i++) { 137 pid_t pid; 138 139 pid = fork(); 140 if (pid < 0) 141 return fret; 142 143 if (pid == 0) 144 exit(EXIT_SUCCESS); 145 146 wait_for_pid(pid); 147 if (pid >= 500) { 148 fprintf(stderr, "Managed to create process with pid %d beyond configured limit\n", pid); 149 return fret; 150 } 151 } 152 153 return 0; 154 } 155 156 static int pid_max_nested_outer(void *data) 157 { 158 int fret = -1, nr_procs = 400; 159 pid_t pids[1000]; 160 int fd, i, ret; 161 pid_t pid; 162 163 ret = mount("", "/", NULL, MS_PRIVATE | MS_REC, 0); 164 if (ret) { 165 fprintf(stderr, "%m - Failed to make rootfs private mount\n"); 166 return fret; 167 } 168 169 umount2("/proc", MNT_DETACH); 170 171 ret = mount("proc", "/proc", "proc", 0, NULL); 172 if (ret) { 173 fprintf(stderr, "%m - Failed to mount proc\n"); 174 return fret; 175 } 176 177 fd = open("/proc/sys/kernel/pid_max", O_RDWR | O_CLOEXEC | O_NOCTTY); 178 if (fd < 0) { 179 fprintf(stderr, "%m - Failed to open pid_max\n"); 180 return fret; 181 } 182 183 ret = write(fd, "400", sizeof("400") - 1); 184 close(fd); 185 if (ret < 0) { 186 fprintf(stderr, "%m - Failed to write pid_max\n"); 187 return fret; 188 } 189 190 /* 191 * Create 397 processes. This leaves room for do_clone() (398) and 192 * one more 399. So creating another process needs to fail. 193 */ 194 for (nr_procs = 0; nr_procs < 396; nr_procs++) { 195 pid = fork(); 196 if (pid < 0) 197 goto reap; 198 199 if (pid == 0) 200 exit(EXIT_SUCCESS); 201 202 pids[nr_procs] = pid; 203 } 204 205 pid = do_clone(pid_max_nested_inner, NULL, CLONE_NEWPID | CLONE_NEWNS); 206 if (pid < 0) { 207 fprintf(stderr, "%m - Failed to clone nested pidns\n"); 208 goto reap; 209 } 210 211 if (wait_for_pid(pid)) { 212 fprintf(stderr, "%m - Nested pid_max failed\n"); 213 goto reap; 214 } 215 216 fret = 0; 217 218 reap: 219 for (int i = 0; i < nr_procs; i++) 220 wait_for_pid(pids[i]); 221 222 return fret; 223 } 224 225 static int pid_max_nested_limit_inner(void *data) 226 { 227 int fret = -1, nr_procs = 400; 228 int fd, ret; 229 pid_t pid; 230 pid_t pids[1000]; 231 232 ret = mount("", "/", NULL, MS_PRIVATE | MS_REC, 0); 233 if (ret) { 234 fprintf(stderr, "%m - Failed to make rootfs private mount\n"); 235 return fret; 236 } 237 238 umount2("/proc", MNT_DETACH); 239 240 ret = mount("proc", "/proc", "proc", 0, NULL); 241 if (ret) { 242 fprintf(stderr, "%m - Failed to mount proc\n"); 243 return fret; 244 } 245 246 fd = open("/proc/sys/kernel/pid_max", O_RDWR | O_CLOEXEC | O_NOCTTY); 247 if (fd < 0) { 248 fprintf(stderr, "%m - Failed to open pid_max\n"); 249 return fret; 250 } 251 252 ret = write(fd, "500", sizeof("500") - 1); 253 close(fd); 254 if (ret < 0) { 255 fprintf(stderr, "%m - Failed to write pid_max\n"); 256 return fret; 257 } 258 259 for (nr_procs = 0; nr_procs < 500; nr_procs++) { 260 pid = fork(); 261 if (pid < 0) 262 break; 263 264 if (pid == 0) 265 exit(EXIT_SUCCESS); 266 267 pids[nr_procs] = pid; 268 } 269 270 if (nr_procs >= 400) { 271 fprintf(stderr, "Managed to create processes beyond the configured outer limit\n"); 272 goto reap; 273 } 274 275 fret = 0; 276 277 reap: 278 for (int i = 0; i < nr_procs; i++) 279 wait_for_pid(pids[i]); 280 281 return fret; 282 } 283 284 static int pid_max_nested_limit_outer(void *data) 285 { 286 int fd, ret; 287 pid_t pid; 288 289 ret = mount("", "/", NULL, MS_PRIVATE | MS_REC, 0); 290 if (ret) { 291 fprintf(stderr, "%m - Failed to make rootfs private mount\n"); 292 return -1; 293 } 294 295 umount2("/proc", MNT_DETACH); 296 297 ret = mount("proc", "/proc", "proc", 0, NULL); 298 if (ret) { 299 fprintf(stderr, "%m - Failed to mount proc\n"); 300 return -1; 301 } 302 303 fd = open("/proc/sys/kernel/pid_max", O_RDWR | O_CLOEXEC | O_NOCTTY); 304 if (fd < 0) { 305 fprintf(stderr, "%m - Failed to open pid_max\n"); 306 return -1; 307 } 308 309 ret = write(fd, "400", sizeof("400") - 1); 310 close(fd); 311 if (ret < 0) { 312 fprintf(stderr, "%m - Failed to write pid_max\n"); 313 return -1; 314 } 315 316 pid = do_clone(pid_max_nested_limit_inner, NULL, CLONE_NEWPID | CLONE_NEWNS); 317 if (pid < 0) { 318 fprintf(stderr, "%m - Failed to clone nested pidns\n"); 319 return -1; 320 } 321 322 if (wait_for_pid(pid)) { 323 fprintf(stderr, "%m - Nested pid_max failed\n"); 324 return -1; 325 } 326 327 return 0; 328 } 329 330 TEST(pid_max_simple) 331 { 332 pid_t pid; 333 334 335 pid = do_clone(pid_max_cb, NULL, CLONE_NEWPID | CLONE_NEWNS); 336 ASSERT_GT(pid, 0); 337 ASSERT_EQ(0, wait_for_pid(pid)); 338 } 339 340 TEST(pid_max_nested_limit) 341 { 342 pid_t pid; 343 344 pid = do_clone(pid_max_nested_limit_outer, NULL, CLONE_NEWPID | CLONE_NEWNS); 345 ASSERT_GT(pid, 0); 346 ASSERT_EQ(0, wait_for_pid(pid)); 347 } 348 349 TEST(pid_max_nested) 350 { 351 pid_t pid; 352 353 pid = do_clone(pid_max_nested_outer, NULL, CLONE_NEWPID | CLONE_NEWNS); 354 ASSERT_GT(pid, 0); 355 ASSERT_EQ(0, wait_for_pid(pid)); 356 } 357 358 TEST_HARNESS_MAIN 359