1 // SPDX-License-Identifier: GPL-2.0
6 #include <linux/kernel.h>
14 #include <sys/resource.h>
15 #include <linux/close_range.h>
17 #include "../kselftest_harness.h"
18 #include "../clone3/clone3_selftests.h"
24 struct __clone_args args
= {
26 .exit_signal
= SIGCHLD
,
30 static char buf
[512], buf2
[512];
34 fd
= open("/proc/sys/fs/nr_open", O_RDWR
);
37 n
= read(fd
, buf
, sizeof(buf
));
39 ASSERT_EQ(buf
[n
- 1], '\n');
41 ASSERT_EQ(sscanf(buf
, "%d", &nr_open
), 1);
43 ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE
, &rlimit
));
46 n2
= sprintf(buf2
, "%d\n", nr_open
+ 1024);
47 lseek(fd
, 0, SEEK_SET
);
51 rlimit
.rlim_cur
= nr_open
+ 1024;
52 rlimit
.rlim_max
= nr_open
+ 1024;
53 EXPECT_EQ(0, setrlimit(RLIMIT_NOFILE
, &rlimit
)) {
54 lseek(fd
, 0, SEEK_SET
);
59 /* get a descriptor past the old fs.nr_open */
60 EXPECT_GE(dup2(2, nr_open
+ 64), 0) {
61 lseek(fd
, 0, SEEK_SET
);
66 /* get descriptor table shared */
67 pid
= sys_clone3(&args
, sizeof(args
));
69 lseek(fd
, 0, SEEK_SET
);
77 /* restore fs.nr_open */
78 lseek(fd
, 0, SEEK_SET
);
80 /* ... and now unshare(CLONE_FILES) must fail with EMFILE */
81 err
= unshare(CLONE_FILES
);
84 EXPECT_EQ(errno
, EMFILE
)
89 EXPECT_EQ(waitpid(pid
, &status
, 0), pid
);
90 EXPECT_EQ(true, WIFEXITED(status
));
91 EXPECT_EQ(0, WEXITSTATUS(status
));