xref: /linux/tools/testing/selftests/exec/binfmt_misc_interplimit.c (revision f2b69ea2d1a017f0c8e848ff875f4cf2492d2bd0)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * A pre-opened interpreter - what 'F' gives a static entry and what a 'B'
4  * entry binds - keeps a file open for as long as the entry lives, so it pins
5  * the mount it came from. It costs no file descriptor, and binfmt_misc is
6  * FS_USERNS_MOUNT, so an unprivileged user namespace can create them without
7  * bound. Check that UCOUNT_BINFMT_MISC_INTERPRETERS bounds it, that an entry
8  * that pre-opens nothing is not charged, that removing an entry gives the
9  * charge back, and that nesting a user namespace does not evade it.
10  *
11  * Runs unprivileged in a user namespace.
12  */
13 #define _GNU_SOURCE
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <limits.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <sys/mount.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 
23 #include "../filesystems/utils.h"
24 #include "kselftest_harness.h"
25 
26 #define MNT		"/tmp/binfmt_interplimit"
27 #define NESTED_MNT	"/tmp/binfmt_interplimit_nested"
28 #define LIMIT_SYSCTL	"/proc/sys/user/max_binfmt_misc_interpreters"
29 
30 #define MAGIC		"\\xde\\xad"
31 /* Not on the instance, and unlike /bin/true it always exists. */
32 #define INTERP		"/proc/self/exe"
33 
34 /* Small enough to fill by hand, big enough that a refund is visible. */
35 #define LIMIT		4
36 
37 /* What UCOUNT_ENTRY() lets a namespace raise its own limit to. */
38 #define LIMIT_MAX	"2147483647"
39 
40 static int ensure_dir(const char *path)
41 {
42 	if (mkdir(path, 0755) && errno != EEXIST)
43 		return -1;
44 	return 0;
45 }
46 
47 /* Write @val to @path, preserving write(2)'s errno for the caller. */
48 static int write_keep_errno(const char *path, const char *val)
49 {
50 	int fd, saved;
51 	ssize_t n;
52 
53 	fd = open(path, O_WRONLY | O_CLOEXEC);
54 	if (fd < 0)
55 		return -1;
56 	n = write(fd, val, strlen(val));
57 	saved = errno;
58 	close(fd);
59 	errno = saved;
60 	return n < 0 ? -1 : 0;
61 }
62 
63 static int set_limit(const char *val)
64 {
65 	return write_keep_errno(LIMIT_SYSCTL, val);
66 }
67 
68 static int register_at(const char *mnt, const char *rule)
69 {
70 	char path[PATH_MAX];
71 
72 	snprintf(path, sizeof(path), "%s/register", mnt);
73 	return write_keep_errno(path, rule);
74 }
75 
76 /* An 'F' entry: one interpreter pre-opened at registration, one charge. */
77 static int register_fixed(const char *mnt, const char *name)
78 {
79 	char rule[PATH_MAX];
80 
81 	snprintf(rule, sizeof(rule), ":%s:M::" MAGIC "::" INTERP ":F", name);
82 	return register_at(mnt, rule);
83 }
84 
85 /* The same entry without 'F': the interpreter is opened per exec instead. */
86 static int register_plain(const char *mnt, const char *name)
87 {
88 	char rule[PATH_MAX];
89 
90 	snprintf(rule, sizeof(rule), ":%s:M::" MAGIC "::" INTERP ":", name);
91 	return register_at(mnt, rule);
92 }
93 
94 static int remove_entry(const char *mnt, const char *name)
95 {
96 	char path[PATH_MAX];
97 
98 	snprintf(path, sizeof(path), "%s/%s", mnt, name);
99 	return write_keep_errno(path, "-1\n");
100 }
101 
102 static bool entry_exists(const char *mnt, const char *name)
103 {
104 	char path[PATH_MAX];
105 
106 	snprintf(path, sizeof(path), "%s/%s", mnt, name);
107 	return access(path, F_OK) == 0;
108 }
109 
110 /* Register @n 'F' entries, each with a name of its own. */
111 static int fill_budget(const char *mnt, unsigned int n)
112 {
113 	char name[32];
114 	unsigned int i;
115 
116 	for (i = 0; i < n; i++) {
117 		snprintf(name, sizeof(name), "fixed%u", i);
118 		if (register_fixed(mnt, name))
119 			return -1;
120 	}
121 	return 0;
122 }
123 
124 FIXTURE(interp_limit) {
125 };
126 
127 FIXTURE_SETUP(interp_limit)
128 {
129 	/* setup_userns() exits rather than returns if this is not there. */
130 	if (access("/proc/self/ns/user", F_OK))
131 		SKIP(return, "kernel without user namespaces");
132 	ASSERT_EQ(setup_userns(), 0);
133 
134 	/* CAP_SYS_RESOURCE in this namespace is what makes it writable. */
135 	if (set_limit(LIMIT_MAX)) {
136 		if (errno == ENOENT)
137 			SKIP(return, "kernel without " LIMIT_SYSCTL);
138 		SKIP(return, "cannot set the limit: %s", strerror(errno));
139 	}
140 
141 	ASSERT_EQ(ensure_dir(MNT), 0);
142 	if (mount("binfmt_misc", MNT, "binfmt_misc", 0, NULL)) {
143 		int saved = errno;
144 
145 		/* Teardown doesn't run when setup skips, so clean up here. */
146 		rmdir(MNT);
147 		SKIP(return, "no binfmt_misc: %s", strerror(saved));
148 	}
149 }
150 
151 FIXTURE_TEARDOWN(interp_limit)
152 {
153 	/* The namespaces go with the process; just don't litter /tmp. */
154 	umount2(NESTED_MNT, MNT_DETACH);
155 	umount2(MNT, MNT_DETACH);
156 	rmdir(NESTED_MNT);
157 	rmdir(MNT);
158 }
159 
160 /* Every pre-opened interpreter is charged, and the budget is a hard stop. */
161 TEST_F(interp_limit, fixed_interpreters_are_charged)
162 {
163 	char buf[32];
164 
165 	snprintf(buf, sizeof(buf), "%u", LIMIT);
166 	ASSERT_EQ(set_limit(buf), 0);
167 
168 	ASSERT_EQ(fill_budget(MNT, LIMIT), 0);
169 
170 	EXPECT_NE(register_fixed(MNT, "over"), 0);
171 	EXPECT_EQ(errno, ENOSPC);
172 
173 	/* A refused registration leaves nothing behind. */
174 	EXPECT_FALSE(entry_exists(MNT, "over"));
175 }
176 
177 /* An entry that pre-opens nothing pins nothing, so it is not charged. */
178 TEST_F(interp_limit, plain_entries_are_not_charged)
179 {
180 	ASSERT_EQ(set_limit("0"), 0);
181 
182 	EXPECT_EQ(register_plain(MNT, "plain"), 0);
183 	EXPECT_TRUE(entry_exists(MNT, "plain"));
184 
185 	/* ... while the same entry with 'F' has nothing to spend. */
186 	EXPECT_NE(register_fixed(MNT, "fixed"), 0);
187 	EXPECT_EQ(errno, ENOSPC);
188 }
189 
190 /* Removing an entry closes its interpreters and gives the charge back. */
191 TEST_F(interp_limit, removal_refunds_the_charge)
192 {
193 	char buf[32];
194 
195 	snprintf(buf, sizeof(buf), "%u", LIMIT);
196 	ASSERT_EQ(set_limit(buf), 0);
197 
198 	ASSERT_EQ(fill_budget(MNT, LIMIT), 0);
199 	ASSERT_NE(register_fixed(MNT, "over"), 0);
200 
201 	ASSERT_EQ(remove_entry(MNT, "fixed0"), 0);
202 	EXPECT_EQ(register_fixed(MNT, "over"), 0);
203 }
204 
205 /*
206  * The charge walks the ancestors, so a namespace cannot buy itself budget by
207  * nesting: it may raise only its own limit, and the parent it was created
208  * from is charged for every binding made below it.
209  */
210 TEST_F(interp_limit, nesting_does_not_evade_it)
211 {
212 	char buf[32];
213 
214 	snprintf(buf, sizeof(buf), "%u", LIMIT);
215 	ASSERT_EQ(set_limit(buf), 0);
216 	ASSERT_EQ(fill_budget(MNT, LIMIT), 0);
217 
218 	ASSERT_EQ(setup_userns(), 0);
219 	ASSERT_EQ(set_limit(LIMIT_MAX), 0);
220 
221 	ASSERT_EQ(ensure_dir(NESTED_MNT), 0);
222 	ASSERT_EQ(mount("binfmt_misc", NESTED_MNT, "binfmt_misc", 0, NULL), 0);
223 
224 	/* A fresh instance with an unlimited budget of its own, and yet: */
225 	EXPECT_NE(register_fixed(NESTED_MNT, "nested"), 0);
226 	EXPECT_EQ(errno, ENOSPC);
227 
228 	/* The nested instance works for anything that pins no file. */
229 	EXPECT_EQ(register_plain(NESTED_MNT, "nested_plain"), 0);
230 }
231 
232 TEST_HARNESS_MAIN
233