0001
0002
0003 #define _GNU_SOURCE
0004 #include <errno.h>
0005 #include <fcntl.h>
0006 #include <linux/kernel.h>
0007 #include <limits.h>
0008 #include <stdbool.h>
0009 #include <stdio.h>
0010 #include <stdlib.h>
0011 #include <string.h>
0012 #include <syscall.h>
0013 #include <unistd.h>
0014 #include <sys/resource.h>
0015
0016 #include "../kselftest_harness.h"
0017 #include "../clone3/clone3_selftests.h"
0018
0019 #ifndef __NR_close_range
0020 #if defined __alpha__
0021 #define __NR_close_range 546
0022 #elif defined _MIPS_SIM
0023 #if _MIPS_SIM == _MIPS_SIM_ABI32
0024 #define __NR_close_range (436 + 4000)
0025 #endif
0026 #if _MIPS_SIM == _MIPS_SIM_NABI32
0027 #define __NR_close_range (436 + 6000)
0028 #endif
0029 #if _MIPS_SIM == _MIPS_SIM_ABI64
0030 #define __NR_close_range (436 + 5000)
0031 #endif
0032 #elif defined __ia64__
0033 #define __NR_close_range (436 + 1024)
0034 #else
0035 #define __NR_close_range 436
0036 #endif
0037 #endif
0038
0039 #ifndef CLOSE_RANGE_UNSHARE
0040 #define CLOSE_RANGE_UNSHARE (1U << 1)
0041 #endif
0042
0043 #ifndef CLOSE_RANGE_CLOEXEC
0044 #define CLOSE_RANGE_CLOEXEC (1U << 2)
0045 #endif
0046
0047 static inline int sys_close_range(unsigned int fd, unsigned int max_fd,
0048 unsigned int flags)
0049 {
0050 return syscall(__NR_close_range, fd, max_fd, flags);
0051 }
0052
0053 TEST(core_close_range)
0054 {
0055 int i, ret;
0056 int open_fds[101];
0057
0058 for (i = 0; i < ARRAY_SIZE(open_fds); i++) {
0059 int fd;
0060
0061 fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
0062 ASSERT_GE(fd, 0) {
0063 if (errno == ENOENT)
0064 SKIP(return, "Skipping test since /dev/null does not exist");
0065 }
0066
0067 open_fds[i] = fd;
0068 }
0069
0070 EXPECT_EQ(-1, sys_close_range(open_fds[0], open_fds[100], -1)) {
0071 if (errno == ENOSYS)
0072 SKIP(return, "close_range() syscall not supported");
0073 }
0074
0075 EXPECT_EQ(0, sys_close_range(open_fds[0], open_fds[50], 0));
0076
0077 for (i = 0; i <= 50; i++)
0078 EXPECT_EQ(-1, fcntl(open_fds[i], F_GETFL));
0079
0080 for (i = 51; i <= 100; i++)
0081 EXPECT_GT(fcntl(open_fds[i], F_GETFL), -1);
0082
0083
0084 close(57);
0085 close(78);
0086 close(81);
0087 close(82);
0088 close(84);
0089 close(90);
0090
0091 EXPECT_EQ(0, sys_close_range(open_fds[51], open_fds[92], 0));
0092
0093 for (i = 51; i <= 92; i++)
0094 EXPECT_EQ(-1, fcntl(open_fds[i], F_GETFL));
0095
0096 for (i = 93; i <= 100; i++)
0097 EXPECT_GT(fcntl(open_fds[i], F_GETFL), -1);
0098
0099
0100 EXPECT_EQ(0, sys_close_range(open_fds[93], open_fds[99], 0));
0101
0102 for (i = 93; i <= 99; i++)
0103 EXPECT_EQ(-1, fcntl(open_fds[i], F_GETFL));
0104
0105 EXPECT_GT(fcntl(open_fds[i], F_GETFL), -1);
0106
0107 EXPECT_EQ(0, sys_close_range(open_fds[100], open_fds[100], 0));
0108
0109 EXPECT_EQ(-1, fcntl(open_fds[100], F_GETFL));
0110 }
0111
0112 TEST(close_range_unshare)
0113 {
0114 int i, ret, status;
0115 pid_t pid;
0116 int open_fds[101];
0117 struct __clone_args args = {
0118 .flags = CLONE_FILES,
0119 .exit_signal = SIGCHLD,
0120 };
0121
0122 for (i = 0; i < ARRAY_SIZE(open_fds); i++) {
0123 int fd;
0124
0125 fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
0126 ASSERT_GE(fd, 0) {
0127 if (errno == ENOENT)
0128 SKIP(return, "Skipping test since /dev/null does not exist");
0129 }
0130
0131 open_fds[i] = fd;
0132 }
0133
0134 pid = sys_clone3(&args, sizeof(args));
0135 ASSERT_GE(pid, 0);
0136
0137 if (pid == 0) {
0138 ret = sys_close_range(open_fds[0], open_fds[50],
0139 CLOSE_RANGE_UNSHARE);
0140 if (ret)
0141 exit(EXIT_FAILURE);
0142
0143 for (i = 0; i <= 50; i++)
0144 if (fcntl(open_fds[i], F_GETFL) != -1)
0145 exit(EXIT_FAILURE);
0146
0147 for (i = 51; i <= 100; i++)
0148 if (fcntl(open_fds[i], F_GETFL) == -1)
0149 exit(EXIT_FAILURE);
0150
0151
0152 close(57);
0153 close(78);
0154 close(81);
0155 close(82);
0156 close(84);
0157 close(90);
0158
0159 ret = sys_close_range(open_fds[51], open_fds[92],
0160 CLOSE_RANGE_UNSHARE);
0161 if (ret)
0162 exit(EXIT_FAILURE);
0163
0164 for (i = 51; i <= 92; i++)
0165 if (fcntl(open_fds[i], F_GETFL) != -1)
0166 exit(EXIT_FAILURE);
0167
0168 for (i = 93; i <= 100; i++)
0169 if (fcntl(open_fds[i], F_GETFL) == -1)
0170 exit(EXIT_FAILURE);
0171
0172
0173 ret = sys_close_range(open_fds[93], open_fds[99],
0174 CLOSE_RANGE_UNSHARE);
0175 if (ret)
0176 exit(EXIT_FAILURE);
0177
0178 for (i = 93; i <= 99; i++)
0179 if (fcntl(open_fds[i], F_GETFL) != -1)
0180 exit(EXIT_FAILURE);
0181
0182 if (fcntl(open_fds[100], F_GETFL) == -1)
0183 exit(EXIT_FAILURE);
0184
0185 ret = sys_close_range(open_fds[100], open_fds[100],
0186 CLOSE_RANGE_UNSHARE);
0187 if (ret)
0188 exit(EXIT_FAILURE);
0189
0190 if (fcntl(open_fds[100], F_GETFL) != -1)
0191 exit(EXIT_FAILURE);
0192
0193 exit(EXIT_SUCCESS);
0194 }
0195
0196 EXPECT_EQ(waitpid(pid, &status, 0), pid);
0197 EXPECT_EQ(true, WIFEXITED(status));
0198 EXPECT_EQ(0, WEXITSTATUS(status));
0199 }
0200
0201 TEST(close_range_unshare_capped)
0202 {
0203 int i, ret, status;
0204 pid_t pid;
0205 int open_fds[101];
0206 struct __clone_args args = {
0207 .flags = CLONE_FILES,
0208 .exit_signal = SIGCHLD,
0209 };
0210
0211 for (i = 0; i < ARRAY_SIZE(open_fds); i++) {
0212 int fd;
0213
0214 fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
0215 ASSERT_GE(fd, 0) {
0216 if (errno == ENOENT)
0217 SKIP(return, "Skipping test since /dev/null does not exist");
0218 }
0219
0220 open_fds[i] = fd;
0221 }
0222
0223 pid = sys_clone3(&args, sizeof(args));
0224 ASSERT_GE(pid, 0);
0225
0226 if (pid == 0) {
0227 ret = sys_close_range(open_fds[0], UINT_MAX,
0228 CLOSE_RANGE_UNSHARE);
0229 if (ret)
0230 exit(EXIT_FAILURE);
0231
0232 for (i = 0; i <= 100; i++)
0233 if (fcntl(open_fds[i], F_GETFL) != -1)
0234 exit(EXIT_FAILURE);
0235
0236 exit(EXIT_SUCCESS);
0237 }
0238
0239 EXPECT_EQ(waitpid(pid, &status, 0), pid);
0240 EXPECT_EQ(true, WIFEXITED(status));
0241 EXPECT_EQ(0, WEXITSTATUS(status));
0242 }
0243
0244 TEST(close_range_cloexec)
0245 {
0246 int i, ret;
0247 int open_fds[101];
0248 struct rlimit rlimit;
0249
0250 for (i = 0; i < ARRAY_SIZE(open_fds); i++) {
0251 int fd;
0252
0253 fd = open("/dev/null", O_RDONLY);
0254 ASSERT_GE(fd, 0) {
0255 if (errno == ENOENT)
0256 SKIP(return, "Skipping test since /dev/null does not exist");
0257 }
0258
0259 open_fds[i] = fd;
0260 }
0261
0262 ret = sys_close_range(1000, 1000, CLOSE_RANGE_CLOEXEC);
0263 if (ret < 0) {
0264 if (errno == ENOSYS)
0265 SKIP(return, "close_range() syscall not supported");
0266 if (errno == EINVAL)
0267 SKIP(return, "close_range() doesn't support CLOSE_RANGE_CLOEXEC");
0268 }
0269
0270
0271 ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &rlimit));
0272 rlimit.rlim_cur = 25;
0273 ASSERT_EQ(0, setrlimit(RLIMIT_NOFILE, &rlimit));
0274
0275
0276 ret = sys_close_range(open_fds[0], open_fds[50], CLOSE_RANGE_CLOEXEC);
0277 ASSERT_EQ(0, ret);
0278 ret = sys_close_range(open_fds[75], open_fds[100], CLOSE_RANGE_CLOEXEC);
0279 ASSERT_EQ(0, ret);
0280
0281 for (i = 0; i <= 50; i++) {
0282 int flags = fcntl(open_fds[i], F_GETFD);
0283
0284 EXPECT_GT(flags, -1);
0285 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0286 }
0287
0288 for (i = 51; i <= 74; i++) {
0289 int flags = fcntl(open_fds[i], F_GETFD);
0290
0291 EXPECT_GT(flags, -1);
0292 EXPECT_EQ(flags & FD_CLOEXEC, 0);
0293 }
0294
0295 for (i = 75; i <= 100; i++) {
0296 int flags = fcntl(open_fds[i], F_GETFD);
0297
0298 EXPECT_GT(flags, -1);
0299 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0300 }
0301
0302
0303 ret = sys_close_range(3, UINT_MAX, CLOSE_RANGE_CLOEXEC);
0304 for (i = 0; i <= 100; i++) {
0305 int flags = fcntl(open_fds[i], F_GETFD);
0306
0307 EXPECT_GT(flags, -1);
0308 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0309 }
0310 }
0311
0312 TEST(close_range_cloexec_unshare)
0313 {
0314 int i, ret;
0315 int open_fds[101];
0316 struct rlimit rlimit;
0317
0318 for (i = 0; i < ARRAY_SIZE(open_fds); i++) {
0319 int fd;
0320
0321 fd = open("/dev/null", O_RDONLY);
0322 ASSERT_GE(fd, 0) {
0323 if (errno == ENOENT)
0324 SKIP(return, "Skipping test since /dev/null does not exist");
0325 }
0326
0327 open_fds[i] = fd;
0328 }
0329
0330 ret = sys_close_range(1000, 1000, CLOSE_RANGE_CLOEXEC);
0331 if (ret < 0) {
0332 if (errno == ENOSYS)
0333 SKIP(return, "close_range() syscall not supported");
0334 if (errno == EINVAL)
0335 SKIP(return, "close_range() doesn't support CLOSE_RANGE_CLOEXEC");
0336 }
0337
0338
0339 ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &rlimit));
0340 rlimit.rlim_cur = 25;
0341 ASSERT_EQ(0, setrlimit(RLIMIT_NOFILE, &rlimit));
0342
0343
0344 ret = sys_close_range(open_fds[0], open_fds[50],
0345 CLOSE_RANGE_CLOEXEC | CLOSE_RANGE_UNSHARE);
0346 ASSERT_EQ(0, ret);
0347 ret = sys_close_range(open_fds[75], open_fds[100],
0348 CLOSE_RANGE_CLOEXEC | CLOSE_RANGE_UNSHARE);
0349 ASSERT_EQ(0, ret);
0350
0351 for (i = 0; i <= 50; i++) {
0352 int flags = fcntl(open_fds[i], F_GETFD);
0353
0354 EXPECT_GT(flags, -1);
0355 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0356 }
0357
0358 for (i = 51; i <= 74; i++) {
0359 int flags = fcntl(open_fds[i], F_GETFD);
0360
0361 EXPECT_GT(flags, -1);
0362 EXPECT_EQ(flags & FD_CLOEXEC, 0);
0363 }
0364
0365 for (i = 75; i <= 100; i++) {
0366 int flags = fcntl(open_fds[i], F_GETFD);
0367
0368 EXPECT_GT(flags, -1);
0369 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0370 }
0371
0372
0373 ret = sys_close_range(3, UINT_MAX,
0374 CLOSE_RANGE_CLOEXEC | CLOSE_RANGE_UNSHARE);
0375 for (i = 0; i <= 100; i++) {
0376 int flags = fcntl(open_fds[i], F_GETFD);
0377
0378 EXPECT_GT(flags, -1);
0379 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0380 }
0381 }
0382
0383
0384
0385
0386 TEST(close_range_cloexec_syzbot)
0387 {
0388 int fd1, fd2, fd3, flags, ret, status;
0389 pid_t pid;
0390 struct __clone_args args = {
0391 .flags = CLONE_FILES,
0392 .exit_signal = SIGCHLD,
0393 };
0394
0395
0396 fd1 = open("/dev/null", O_RDWR);
0397 EXPECT_GT(fd1, 0);
0398
0399 fd2 = dup2(fd1, 1000);
0400 EXPECT_GT(fd2, 0);
0401
0402 pid = sys_clone3(&args, sizeof(args));
0403 ASSERT_GE(pid, 0);
0404
0405 if (pid == 0) {
0406 ret = sys_close_range(3, ~0U, CLOSE_RANGE_CLOEXEC);
0407 if (ret)
0408 exit(EXIT_FAILURE);
0409
0410
0411
0412
0413
0414
0415 flags = fcntl(fd1, F_GETFD);
0416 EXPECT_GT(flags, -1);
0417 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0418
0419 flags = fcntl(fd2, F_GETFD);
0420 EXPECT_GT(flags, -1);
0421 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0422
0423 fd3 = dup2(fd1, 42);
0424 EXPECT_GT(fd3, 0);
0425
0426
0427
0428
0429
0430 flags = fcntl(fd3, F_GETFD);
0431 EXPECT_GT(flags, -1);
0432 EXPECT_EQ(flags & FD_CLOEXEC, 0);
0433
0434 exit(EXIT_SUCCESS);
0435 }
0436
0437 EXPECT_EQ(waitpid(pid, &status, 0), pid);
0438 EXPECT_EQ(true, WIFEXITED(status));
0439 EXPECT_EQ(0, WEXITSTATUS(status));
0440
0441
0442
0443
0444
0445 flags = fcntl(fd1, F_GETFD);
0446 EXPECT_GT(flags, -1);
0447 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0448
0449 flags = fcntl(fd2, F_GETFD);
0450 EXPECT_GT(flags, -1);
0451 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0452
0453 fd3 = dup2(fd1, 42);
0454 EXPECT_GT(fd3, 0);
0455
0456 flags = fcntl(fd3, F_GETFD);
0457 EXPECT_GT(flags, -1);
0458 EXPECT_EQ(flags & FD_CLOEXEC, 0);
0459
0460 EXPECT_EQ(close(fd1), 0);
0461 EXPECT_EQ(close(fd2), 0);
0462 EXPECT_EQ(close(fd3), 0);
0463 }
0464
0465
0466
0467
0468 TEST(close_range_cloexec_unshare_syzbot)
0469 {
0470 int i, fd1, fd2, fd3, flags, ret, status;
0471 pid_t pid;
0472 struct __clone_args args = {
0473 .flags = CLONE_FILES,
0474 .exit_signal = SIGCHLD,
0475 };
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488 fd1 = open("/dev/null", O_RDWR);
0489 EXPECT_GT(fd1, 0);
0490
0491 fd2 = dup2(fd1, 1000);
0492 EXPECT_GT(fd2, 0);
0493
0494 for (i = 0; i < 100; i++) {
0495
0496 pid = sys_clone3(&args, sizeof(args));
0497 ASSERT_GE(pid, 0);
0498
0499 if (pid == 0) {
0500 ret = sys_close_range(3, ~0U, CLOSE_RANGE_UNSHARE |
0501 CLOSE_RANGE_CLOEXEC);
0502 if (ret)
0503 exit(EXIT_FAILURE);
0504
0505
0506
0507
0508
0509
0510 flags = fcntl(fd1, F_GETFD);
0511 EXPECT_GT(flags, -1);
0512 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0513
0514 flags = fcntl(fd2, F_GETFD);
0515 EXPECT_GT(flags, -1);
0516 EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
0517
0518 fd3 = dup2(fd1, 42);
0519 EXPECT_GT(fd3, 0);
0520
0521
0522
0523
0524
0525 flags = fcntl(fd3, F_GETFD);
0526 EXPECT_GT(flags, -1);
0527 EXPECT_EQ(flags & FD_CLOEXEC, 0);
0528
0529 EXPECT_EQ(close(fd1), 0);
0530 EXPECT_EQ(close(fd2), 0);
0531 EXPECT_EQ(close(fd3), 0);
0532
0533 exit(EXIT_SUCCESS);
0534 }
0535
0536 EXPECT_EQ(waitpid(pid, &status, 0), pid);
0537 EXPECT_EQ(true, WIFEXITED(status));
0538 EXPECT_EQ(0, WEXITSTATUS(status));
0539 }
0540
0541
0542
0543
0544
0545
0546 flags = fcntl(fd1, F_GETFD);
0547 EXPECT_GT(flags, -1);
0548 EXPECT_EQ(flags & FD_CLOEXEC, 0);
0549
0550 flags = fcntl(fd2, F_GETFD);
0551 EXPECT_GT(flags, -1);
0552 EXPECT_EQ(flags & FD_CLOEXEC, 0);
0553
0554 fd3 = dup2(fd1, 42);
0555 EXPECT_GT(fd3, 0);
0556
0557 flags = fcntl(fd3, F_GETFD);
0558 EXPECT_GT(flags, -1);
0559 EXPECT_EQ(flags & FD_CLOEXEC, 0);
0560
0561 EXPECT_EQ(close(fd1), 0);
0562 EXPECT_EQ(close(fd2), 0);
0563 EXPECT_EQ(close(fd3), 0);
0564 }
0565
0566 TEST_HARNESS_MAIN