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