Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / testing / selftests / core / unshare_test.c
blob7fec9dfb1b0e3ab735b1d3fae1fd993799421f10
1 // SPDX-License-Identifier: GPL-2.0
3 #define _GNU_SOURCE
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <linux/kernel.h>
7 #include <limits.h>
8 #include <stdbool.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <syscall.h>
13 #include <unistd.h>
14 #include <sys/resource.h>
15 #include <linux/close_range.h>
17 #include "../kselftest_harness.h"
18 #include "../clone3/clone3_selftests.h"
20 TEST(unshare_EMFILE)
22 pid_t pid;
23 int status;
24 struct __clone_args args = {
25 .flags = CLONE_FILES,
26 .exit_signal = SIGCHLD,
28 int fd;
29 ssize_t n, n2;
30 static char buf[512], buf2[512];
31 struct rlimit rlimit;
32 int nr_open;
34 fd = open("/proc/sys/fs/nr_open", O_RDWR);
35 ASSERT_GE(fd, 0);
37 n = read(fd, buf, sizeof(buf));
38 ASSERT_GT(n, 0);
39 ASSERT_EQ(buf[n - 1], '\n');
41 ASSERT_EQ(sscanf(buf, "%d", &nr_open), 1);
43 ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &rlimit));
45 /* bump fs.nr_open */
46 n2 = sprintf(buf2, "%d\n", nr_open + 1024);
47 lseek(fd, 0, SEEK_SET);
48 write(fd, buf2, n2);
50 /* bump ulimit -n */
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);
55 write(fd, buf, n);
56 exit(EXIT_FAILURE);
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);
62 write(fd, buf, n);
63 exit(EXIT_FAILURE);
66 /* get descriptor table shared */
67 pid = sys_clone3(&args, sizeof(args));
68 EXPECT_GE(pid, 0) {
69 lseek(fd, 0, SEEK_SET);
70 write(fd, buf, n);
71 exit(EXIT_FAILURE);
74 if (pid == 0) {
75 int err;
77 /* restore fs.nr_open */
78 lseek(fd, 0, SEEK_SET);
79 write(fd, buf, n);
80 /* ... and now unshare(CLONE_FILES) must fail with EMFILE */
81 err = unshare(CLONE_FILES);
82 EXPECT_EQ(err, -1)
83 exit(EXIT_FAILURE);
84 EXPECT_EQ(errno, EMFILE)
85 exit(EXIT_FAILURE);
86 exit(EXIT_SUCCESS);
89 EXPECT_EQ(waitpid(pid, &status, 0), pid);
90 EXPECT_EQ(true, WIFEXITED(status));
91 EXPECT_EQ(0, WEXITSTATUS(status));
94 TEST_HARNESS_MAIN