Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.10.11.
 1// SPDX-License-Identifier: GPL-2.0
 2
 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>
16
17#include "../kselftest_harness.h"
18#include "../clone3/clone3_selftests.h"
19
20TEST(unshare_EMFILE)
21{
22	pid_t pid;
23	int status;
24	struct __clone_args args = {
25		.flags = CLONE_FILES,
26		.exit_signal = SIGCHLD,
27	};
28	int fd;
29	ssize_t n, n2;
30	static char buf[512], buf2[512];
31	struct rlimit rlimit;
32	int nr_open;
33
34	fd = open("/proc/sys/fs/nr_open", O_RDWR);
35	ASSERT_GE(fd, 0);
36
37	n = read(fd, buf, sizeof(buf));
38	ASSERT_GT(n, 0);
39	ASSERT_EQ(buf[n - 1], '\n');
40
41	ASSERT_EQ(sscanf(buf, "%d", &nr_open), 1);
42
43	ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &rlimit));
44
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);
49
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);
57	}
58
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);
64	}
65
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);
72	}
73
74	if (pid == 0) {
75		int err;
76
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);
87	}
88
89	EXPECT_EQ(waitpid(pid, &status, 0), pid);
90	EXPECT_EQ(true, WIFEXITED(status));
91	EXPECT_EQ(0, WEXITSTATUS(status));
92}
93
94TEST_HARNESS_MAIN