xref: /linux/tools/testing/selftests/exec/binfmt_misc_bpf.c (revision b9cba7ebfe539f3e4bbdd03a1e0efa3b30b3f592)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Selftest for binfmt_misc bpf-backed ('B') handlers.
4  *
5  * A handler is a struct binfmt_misc_ops struct_ops map with a sleepable match
6  * and a sleepable load program. Attaching it publishes it by name in the
7  * caller's user namespace; a 'B' entry referencing it by name in the
8  * interpreter field activates it:
9  *
10  *     echo ':name:B::::<handler>:' > /proc/sys/fs/binfmt_misc/register
11  *
12  * Five self-contained cases are exercised:
13  *
14  *   1. bpf_interp: the match program matches a synthetic aarch64 ELF header
15  *      from the prefetched bprm->buf and the load program routes it to a
16  *      fixed interpreter of its choosing.
17  *   2. nix_origin: the match program reads the binary's program headers to
18  *      commit only to a "$ORIGIN/..."-relative PT_INTERP and the load program
19  *      resolves it to an interpreter co-located with the binary (the
20  *      relocatable-loader case the kernel ELF loader cannot express).
21  *   3. transparent: the load program sets BPF_BINPRM_TRANSPARENT; the
22  *      asserting interpreter (binfmt_transparent_interp) verifies the
23  *      identity the kernel constructed (exe link, argv, cmdline, comm,
24  *      AT_EXECFD, write denial) from inside the process.
25  *   4. loader: the load program sets BPF_BINPRM_LOADER; the payload
26  *      (binfmt_loader_payload) runs as the main image with the selected
27  *      interpreter substituted for its PT_INTERP and asserts the native
28  *      identity from inside.
29  *   5. interp_bind: an entry registered disabled with 'D' is given its
30  *      interpreters one write at a time, and the load program picks one by
31  *      name per exec. Replacing what the path holds afterwards changes
32  *      nothing, which is the point of binding a file rather than resolving
33  *      a name at exec time. Enabling the entry seals it.
34  *
35  * The first two route to a test interpreter that prints BPF_INTERP_RAN,
36  * proving the program's chosen interpreter actually ran.
37  */
38 #define _GNU_SOURCE
39 #include <elf.h>
40 #include <limits.h>
41 #include <sched.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46 #include <fcntl.h>
47 
48 #include <bpf/btf.h>
49 #include <bpf/libbpf.h>
50 
51 #include "binfmt_misc_common.h"
52 #include "kselftest_harness.h"
53 
54 #define INTERP_PATH	"/tmp/binfmt_bpf_interp"
55 #define AARCH64_PATH	"/tmp/binfmt_bpf_aarch64"
56 #define RELOC_TEMPLATE	"/tmp/binfmt_relocXXXXXX"
57 #define TRANS_INTERP	"/tmp/binfmt_transparent_interp"
58 #define TRANS_PATH	"/tmp/binfmt_bpf_riscv"
59 #define EXPECT		"BPF_INTERP_RAN"
60 #define TRANS_EXPECT	"TRANSPARENT_OK"
61 #define LOADER_INTERP	"/tmp/binfmt_loader_interp"
62 #define LOADER_PATH	"/tmp/binfmt_bpf_loader.ldrtest"
63 #define BIND_FIRST	"/tmp/binfmt_bind_first"
64 #define BIND_SECOND	"/tmp/binfmt_bind_second"
65 #define BIND_ARM_PATH	"/tmp/binfmt_bind_arm"
66 #define BIND_RISCV_PATH	"/tmp/binfmt_bind_riscv"
67 #define BIND_EXPECT	"BIND_RAN "
68 #define BIND_MAX	100
69 #define INTERP_LIMIT	"/proc/sys/user/max_binfmt_misc_interpreters"
70 /* Exit status of the binding child when it cannot set up a budget of its own. */
71 #define BIND_NO_BUDGET	200
72 
73 /* A minimal 64-bit little-endian ELF header, padded to the read size. */
74 static int create_fake_elf(const char *path, unsigned short machine)
75 {
76 	unsigned char hdr[256] = {0};
77 	int fd;
78 
79 	hdr[0] = 0x7f; hdr[1] = 'E'; hdr[2] = 'L'; hdr[3] = 'F';
80 	hdr[4] = ELFCLASS64;
81 	hdr[5] = ELFDATA2LSB;
82 	hdr[6] = EV_CURRENT;
83 	hdr[16] = ET_EXEC;
84 	hdr[18] = machine & 0xff;	/* e_machine, little-endian */
85 	hdr[19] = machine >> 8;
86 	hdr[20] = EV_CURRENT;
87 
88 	unlink(path);
89 	fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0755);
90 	if (fd < 0)
91 		return -1;
92 	if (write(fd, hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) {
93 		close(fd);
94 		return -1;
95 	}
96 	close(fd);
97 	return 0;
98 }
99 
100 /*
101  * Register a 'B' entry for @handler. With @flags "D" the entry is created
102  * disabled, which is what leaves it open to being given interpreters.
103  */
104 static int register_entry(const char *name, const char *handler,
105 			  const char *flags)
106 {
107 	char rule[PATH_MAX];
108 
109 	snprintf(rule, sizeof(rule), ":%s:B::::%s:%s", name, handler,
110 		 flags ? flags : "");
111 	return write_reg(rule);
112 }
113 
114 static int check_output(const char *cmd, const char *expected)
115 {
116 	char buf[128];
117 	FILE *fp;
118 
119 	fp = popen(cmd, "r");
120 	if (!fp)
121 		return -1;
122 	if (!fgets(buf, sizeof(buf), fp)) {
123 		pclose(fp);
124 		return -1;
125 	}
126 	pclose(fp);
127 	return strncmp(buf, expected, strlen(expected)) ? -1 : 0;
128 }
129 
130 /* Does the kernel BTF know struct binfmt_misc_ops (CONFIG_BINFMT_MISC_BPF)? */
131 static bool have_binfmt_misc_ops(void)
132 {
133 	struct btf *btf = btf__load_vmlinux_btf();
134 	bool have;
135 
136 	have = btf && btf__find_by_name_kind(btf, "binfmt_misc_ops",
137 					     BTF_KIND_STRUCT) >= 0;
138 	btf__free(btf);
139 	return have;
140 }
141 
142 /* The reason bpf handler cases cannot run here, NULL if they can. */
143 static const char *bpf_handler_unsupported(void)
144 {
145 	if (getuid() != 0)
146 		return "test must be run as root";
147 	if (!have_binfmt_misc_ops())
148 		return "no struct binfmt_misc_ops in the kernel BTF (CONFIG_BINFMT_MISC_BPF)";
149 	if (!binfmt_misc_available())
150 		return "no binfmt_misc";
151 	return NULL;
152 }
153 
154 /* An attached handler with its 'B' entry activated. */
155 struct bpf_case {
156 	struct bpf_object *obj;
157 	struct bpf_link *link;
158 	const char *entry;
159 };
160 
161 /*
162  * Load @objfile, attach its struct_ops map @handler (which publishes the
163  * handler) and register a 'B' entry named @entry that references it, with
164  * @flags as the entry's register-string flags.
165  */
166 static int bpf_case_start_flags(struct bpf_case *c, const char *objfile,
167 				const char *handler, const char *entry,
168 				const char *flags)
169 {
170 	struct bpf_map *map;
171 
172 	c->obj = NULL;
173 	c->link = NULL;
174 	c->entry = entry;
175 
176 	c->obj = bpf_object__open_file(objfile, NULL);
177 	if (!c->obj || libbpf_get_error(c->obj)) {
178 		fprintf(stderr, "open %s failed\n", objfile);
179 		c->obj = NULL;
180 		return -1;
181 	}
182 	if (bpf_object__load(c->obj)) {
183 		fprintf(stderr, "load %s failed (check dmesg for the verifier log)\n",
184 			objfile);
185 		goto fail;
186 	}
187 	map = bpf_object__find_map_by_name(c->obj, handler);
188 	if (!map) {
189 		fprintf(stderr, "no struct_ops map '%s' in %s\n", handler, objfile);
190 		goto fail;
191 	}
192 	c->link = bpf_map__attach_struct_ops(map);
193 	if (!c->link || libbpf_get_error(c->link)) {
194 		fprintf(stderr, "attach struct_ops '%s' failed\n", handler);
195 		c->link = NULL;
196 		goto fail;
197 	}
198 	if (register_entry(entry, handler, flags)) {
199 		fprintf(stderr, "register 'B' entry '%s' failed\n", entry);
200 		goto fail;
201 	}
202 	return 0;
203 
204 fail:
205 	bpf_link__destroy(c->link);
206 	bpf_object__close(c->obj);
207 	c->obj = NULL;
208 	c->link = NULL;
209 	return -1;
210 }
211 
212 static int bpf_case_start(struct bpf_case *c, const char *objfile,
213 			  const char *handler, const char *entry)
214 {
215 	return bpf_case_start_flags(c, objfile, handler, entry, NULL);
216 }
217 
218 static void bpf_case_stop(struct bpf_case *c)
219 {
220 	unregister(c->entry);
221 	bpf_link__destroy(c->link);
222 	bpf_object__close(c->obj);
223 }
224 
225 /* Activate @handler, run @target and check it produced @expect. */
226 static int run_case(const char *objfile, const char *handler,
227 		    const char *entry, const char *target, const char *expect)
228 {
229 	struct bpf_case c;
230 	int ret;
231 
232 	if (bpf_case_start(&c, objfile, handler, entry))
233 		return -1;
234 	ret = check_output(target, expect);
235 	bpf_case_stop(&c);
236 	return ret;
237 }
238 
239 FIXTURE(bpf_handler) {
240 	char obj[PATH_MAX];	/* struct_ops object of the case under test */
241 };
242 
243 FIXTURE_SETUP(bpf_handler)
244 {
245 	char src[PATH_MAX];
246 	const char *why = bpf_handler_unsupported();
247 
248 	if (why)
249 		SKIP(return, "%s", why);
250 
251 	/* Shared test interpreter. */
252 	ASSERT_EQ(artifact_path(src, sizeof(src), "binfmt_bpf_interp"), 0);
253 	ASSERT_EQ(copy_file(src, INTERP_PATH), 0);
254 }
255 
256 FIXTURE_TEARDOWN(bpf_handler)
257 {
258 	unlink(INTERP_PATH);
259 }
260 
261 /* The match program matches a synthetic header, the load program routes it. */
262 TEST_F(bpf_handler, fixed_interpreter)
263 {
264 	ASSERT_EQ(create_fake_elf(AARCH64_PATH, EM_AARCH64), 0);
265 	ASSERT_EQ(artifact_path(self->obj, sizeof(self->obj),
266 				"bpf_interp.bpf.o"), 0);
267 	EXPECT_EQ(run_case(self->obj, "bpf_interp", "test_bpf_interp",
268 			   AARCH64_PATH, EXPECT), 0);
269 	unlink(AARCH64_PATH);
270 }
271 
272 /* A "$ORIGIN/..." PT_INTERP resolved to an interpreter next to the binary. */
273 TEST_F(bpf_handler, origin_relative_interpreter)
274 {
275 	char src[PATH_MAX], app[PATH_MAX], interp[PATH_MAX];
276 	char dir[] = RELOC_TEMPLATE;
277 
278 	ASSERT_NE(mkdtemp(dir), NULL);
279 	snprintf(app, sizeof(app), "%s/app", dir);
280 	snprintf(interp, sizeof(interp), "%s/binfmt_bpf_interp", dir);
281 	ASSERT_EQ(artifact_path(src, sizeof(src), "binfmt_bpf_app"), 0);
282 	ASSERT_EQ(copy_file(src, app), 0);
283 	ASSERT_EQ(copy_file(INTERP_PATH, interp), 0);
284 
285 	ASSERT_EQ(artifact_path(self->obj, sizeof(self->obj),
286 				"nix_origin.bpf.o"), 0);
287 	EXPECT_EQ(run_case(self->obj, "nix_origin", "test_bpf_origin",
288 			   app, EXPECT), 0);
289 
290 	unlink(app);
291 	unlink(interp);
292 	rmdir(dir);
293 }
294 
295 /* A transparent dispatch: the process presents as the binary, not the interp. */
296 TEST_F(bpf_handler, transparent_dispatch)
297 {
298 	char src[PATH_MAX], cmd[PATH_MAX + 16];
299 
300 	/* Probe for transparent-mode support via its static counterpart. */
301 	if (!binfmt_flag_supported('T'))
302 		SKIP(return, "kernel without transparent mode");
303 
304 	ASSERT_EQ(artifact_path(src, sizeof(src), "binfmt_transparent_interp"), 0);
305 	ASSERT_EQ(copy_file(src, TRANS_INTERP), 0);
306 	ASSERT_EQ(create_fake_elf(TRANS_PATH, EM_RISCV), 0);
307 
308 	setenv("BINFMT_TEST_BINARY", TRANS_PATH, 1);
309 	snprintf(cmd, sizeof(cmd), "%s argone argtwo", TRANS_PATH);
310 	ASSERT_EQ(artifact_path(self->obj, sizeof(self->obj),
311 				"transparent.bpf.o"), 0);
312 	EXPECT_EQ(run_case(self->obj, "transparent", "test_bpf_transparent",
313 			   cmd, TRANS_EXPECT), 0);
314 
315 	unlink(TRANS_PATH);
316 	unlink(TRANS_INTERP);
317 }
318 
319 /* A per-exec loader substitution: the payload runs as a native exec. */
320 TEST_F(bpf_handler, loader_substitution)
321 {
322 	char src[PATH_MAX], loader[PATH_MAX];
323 	struct bpf_case c;
324 	int status;
325 
326 	if (find_loader(loader, sizeof(loader)))
327 		SKIP(return, "cannot determine own PT_INTERP");
328 
329 	ASSERT_EQ(copy_file(loader, LOADER_INTERP), 0);
330 	ASSERT_EQ(artifact_path(src, sizeof(src), "binfmt_loader_payload"), 0);
331 	ASSERT_EQ(copy_file(src, LOADER_PATH), 0);
332 	ASSERT_EQ(patch_file(LOADER_PATH, EI_PAD, LOADER_MARKER,
333 			     strlen(LOADER_MARKER)), 0);
334 	ASSERT_EQ(artifact_path(self->obj, sizeof(self->obj),
335 				"loader.bpf.o"), 0);
336 
337 	setenv("BINFMT_TEST_BINARY", LOADER_PATH, 1);
338 	setenv("BINFMT_TEST_INTERP", LOADER_INTERP, 1);
339 
340 	ASSERT_EQ(bpf_case_start(&c, self->obj, "loader", "test_bpf_loader"), 0);
341 	status = run_payload(LOADER_PATH);
342 	bpf_case_stop(&c);
343 	EXPECT_EQ(status, 0);
344 
345 	unsetenv("BINFMT_TEST_INTERP");
346 	unlink(LOADER_PATH);
347 	unlink(LOADER_INTERP);
348 }
349 
350 /* The errno an exec of @path fails with, 0 if it succeeded. */
351 static int exec_errno(const char *path)
352 {
353 	int status;
354 	pid_t pid;
355 
356 	pid = fork();
357 	if (pid == 0) {
358 		execl(path, path, (char *)NULL);
359 		_exit(errno);
360 	}
361 	if (pid < 0 || waitpid(pid, &status, 0) != pid || !WIFEXITED(status))
362 		return -1;
363 	return WEXITSTATUS(status);
364 }
365 
366 /* Install a copy of the bound-interpreter test binary at @path. */
367 static int install_interp(const char *path)
368 {
369 	char src[PATH_MAX];
370 
371 	if (artifact_path(src, sizeof(src), "binfmt_bind_interp"))
372 		return -1;
373 	return copy_file(src, path);
374 }
375 
376 /* Bind @path to @entry under @name, the '+' command of a disabled entry. */
377 static int entry_bind(const char *entry, const char *name, const char *path)
378 {
379 	char cmd[PATH_MAX];
380 
381 	snprintf(cmd, sizeof(cmd), "+%s %s\n", name, path);
382 	return entry_command(entry, cmd);
383 }
384 
385 /* Set the interpreter budget of this namespace. */
386 static int write_interp_limit(const char *val)
387 {
388 	ssize_t n;
389 	int fd;
390 
391 	fd = open(INTERP_LIMIT, O_WRONLY | O_CLOEXEC);
392 	if (fd < 0)
393 		return -1;
394 	n = write(fd, val, strlen(val));
395 	close(fd);
396 	return n < 0 ? -1 : 0;
397 }
398 
399 /*
400  * The errno a bind is refused with when the writer is a child that has spent
401  * the budget of a user namespace of its own, 0 if it succeeded and -1 if the
402  * child could not set itself up. The fd is opened here and inherited, so the
403  * interpreter is still opened with this process's credentials.
404  */
405 static int bind_out_of_budget(const char *entry, const char *name,
406 			      const char *path)
407 {
408 	char cmd[PATH_MAX], file[PATH_MAX];
409 	int fd, status, retval;
410 	pid_t pid;
411 
412 	snprintf(file, sizeof(file), BINFMT_DIR "/%s", entry);
413 	snprintf(cmd, sizeof(cmd), "+%s %s\n", name, path);
414 
415 	fd = open(file, O_WRONLY | O_CLOEXEC);
416 	if (fd < 0)
417 		return -1;
418 
419 	pid = fork();
420 	if (pid == 0) {
421 		ssize_t n;
422 
423 		/* A namespace of its own, with nothing left in it to spend. */
424 		if (unshare(CLONE_NEWUSER) || write_interp_limit("0"))
425 			_exit(BIND_NO_BUDGET);
426 		n = write(fd, cmd, strlen(cmd));
427 		_exit(n < 0 ? errno : 0);
428 	}
429 	close(fd);
430 	if (pid < 0 || waitpid(pid, &status, 0) != pid || !WIFEXITED(status))
431 		return -1;
432 	retval = WEXITSTATUS(status);
433 	return retval == BIND_NO_BUDGET ? -1 : retval;
434 }
435 
436 FIXTURE(bound_interp) {
437 	char obj[PATH_MAX];
438 	struct bpf_case c;
439 	bool started;
440 };
441 
442 FIXTURE_SETUP(bound_interp)
443 {
444 	const char *why = bpf_handler_unsupported();
445 
446 	if (why)
447 		SKIP(return, "%s", why);
448 	if (!binfmt_flag_supported('D')) {
449 		ASSERT_EQ(errno, EINVAL);
450 		SKIP(return, "kernel without the 'D' flag");
451 	}
452 
453 	ASSERT_EQ(install_interp(BIND_FIRST), 0);
454 	ASSERT_EQ(install_interp(BIND_SECOND), 0);
455 
456 	ASSERT_EQ(artifact_path(self->obj, sizeof(self->obj),
457 				"interp_bind.bpf.o"), 0);
458 
459 	/*
460 	 * Registered disabled, so it cannot be matched yet and can still be
461 	 * given interpreters. Each path is resolved once, by its write(2);
462 	 * from here on the entry holds the files themselves.
463 	 */
464 	ASSERT_EQ(bpf_case_start_flags(&self->c, self->obj, "interp_bind",
465 				       "test_interp_bind", "D"), 0);
466 	self->started = true;
467 
468 	ASSERT_EQ(entry_bind("test_interp_bind", "first", BIND_FIRST), 0);
469 	ASSERT_EQ(entry_bind("test_interp_bind", "second", BIND_SECOND), 0);
470 }
471 
472 FIXTURE_TEARDOWN(bound_interp)
473 {
474 	if (self->started)
475 		bpf_case_stop(&self->c);
476 	unlink(BIND_FIRST);
477 	unlink(BIND_SECOND);
478 	unlink(AARCH64_PATH);
479 	unlink(BIND_RISCV_PATH);
480 	unlink(BIND_ARM_PATH);
481 }
482 
483 /* Enabling is what makes the configured entry matchable. */
484 static int activate(const char *entry)
485 {
486 	return entry_command(entry, "1\n");
487 }
488 
489 /* One entry, one interpreter per guest architecture, picked per exec. */
490 TEST_F(bound_interp, selects_by_name)
491 {
492 	ASSERT_EQ(create_fake_elf(AARCH64_PATH, EM_AARCH64), 0);
493 	ASSERT_EQ(create_fake_elf(BIND_RISCV_PATH, EM_RISCV), 0);
494 
495 	/* Disabled, so it does not match and no format claims the binary. */
496 	EXPECT_EQ(exec_errno(AARCH64_PATH), ENOEXEC);
497 
498 	ASSERT_EQ(activate("test_interp_bind"), 0);
499 	EXPECT_EQ(check_output(AARCH64_PATH, BIND_EXPECT BIND_FIRST), 0);
500 	EXPECT_EQ(check_output(BIND_RISCV_PATH, BIND_EXPECT BIND_SECOND), 0);
501 }
502 
503 /* What was bound is what runs, whatever the path holds afterwards. */
504 TEST_F(bound_interp, path_no_longer_decides)
505 {
506 	char other[PATH_MAX];
507 
508 	ASSERT_EQ(create_fake_elf(AARCH64_PATH, EM_AARCH64), 0);
509 	ASSERT_EQ(activate("test_interp_bind"), 0);
510 
511 	/* Bound interpreters are pinned against writes, exactly like 'F'. */
512 	EXPECT_TRUE(write_denied(BIND_FIRST));
513 
514 	/* Replace the path with a different binary: a new file, new inode. */
515 	ASSERT_EQ(artifact_path(other, sizeof(other), "binfmt_bpf_interp"), 0);
516 	ASSERT_EQ(unlink(BIND_FIRST), 0);
517 	ASSERT_EQ(copy_file(other, BIND_FIRST), 0);
518 
519 	EXPECT_EQ(check_output(AARCH64_PATH, BIND_EXPECT BIND_FIRST), 0);
520 }
521 
522 /* The entry reports what it bound, under the names it bound them as. */
523 TEST_F(bound_interp, entry_reports_bindings)
524 {
525 	EXPECT_TRUE(entry_shows("test_interp_bind",
526 				"bpf-interpreter first " BIND_FIRST));
527 	EXPECT_TRUE(entry_shows("test_interp_bind",
528 				"bpf-interpreter second " BIND_SECOND));
529 }
530 
531 /* Selecting a name the entry did not bind fails the exec. */
532 TEST_F(bound_interp, unbound_name_fails)
533 {
534 	ASSERT_EQ(create_fake_elf(BIND_ARM_PATH, EM_ARM), 0);
535 	ASSERT_EQ(activate("test_interp_bind"), 0);
536 
537 	EXPECT_EQ(exec_errno(BIND_ARM_PATH), ENOENT);
538 }
539 
540 /* Activating seals it: what can be matched cannot be changed. */
541 TEST_F(bound_interp, sealed_once_active)
542 {
543 	ASSERT_EQ(activate("test_interp_bind"), 0);
544 
545 	EXPECT_EQ(entry_bind("test_interp_bind", "third", BIND_SECOND), -EBUSY);
546 	EXPECT_FALSE(entry_shows("test_interp_bind",
547 				 "bpf-interpreter third " BIND_SECOND));
548 }
549 
550 /* The seal is for good: disabling the entry again reopens nothing. */
551 TEST_F(bound_interp, disable_does_not_unseal)
552 {
553 	ASSERT_EQ(activate("test_interp_bind"), 0);
554 	ASSERT_EQ(entry_command("test_interp_bind", "0\n"), 0);
555 
556 	EXPECT_EQ(entry_bind("test_interp_bind", "third", BIND_SECOND), -EBUSY);
557 }
558 
559 /* An entry registered without 'D' is sealed from the start. */
560 TEST_F(bound_interp, born_sealed)
561 {
562 	/* A second entry for the handler the fixture already published. */
563 	ASSERT_EQ(register_entry("test_born_sealed", "interp_bind", NULL), 0);
564 
565 	EXPECT_EQ(entry_bind("test_born_sealed", "first", BIND_FIRST), -EBUSY);
566 	unregister("test_born_sealed");
567 }
568 
569 /* A name is bound once; a second use of it is refused. */
570 TEST_F(bound_interp, duplicate_name_refused)
571 {
572 	EXPECT_EQ(entry_bind("test_interp_bind", "first", BIND_SECOND), -EEXIST);
573 }
574 
575 /* A name is a printable word: the entry file reports 'name path' lines. */
576 TEST_F(bound_interp, name_must_be_printable)
577 {
578 	/* A control character would forge a line into the entry file. */
579 	EXPECT_EQ(entry_bind("test_interp_bind", "a\tb", BIND_FIRST), -EINVAL);
580 	EXPECT_EQ(entry_bind("test_interp_bind", "a\nb", BIND_FIRST), -EINVAL);
581 
582 	/* A space cannot even be spelled: the path starts after the first one. */
583 	EXPECT_EQ(entry_bind("test_interp_bind", "a b", BIND_FIRST), -EINVAL);
584 }
585 
586 /* The command ends at the write: bytes past an embedded nul are refused. */
587 TEST_F(bound_interp, trailing_bytes_refused)
588 {
589 	char cmd[PATH_MAX];
590 	size_t len;
591 	int fd;
592 
593 	/* entry_command() cannot spell a nul, so write the buffer raw. */
594 	snprintf(cmd, sizeof(cmd), "+nul %s", BIND_FIRST);
595 	len = strlen(cmd) + 1;
596 	memcpy(cmd + len, "junk", sizeof("junk"));
597 	len += sizeof("junk");
598 
599 	fd = open(BINFMT_DIR "/test_interp_bind", O_WRONLY | O_CLOEXEC);
600 	ASSERT_GE(fd, 0);
601 	EXPECT_EQ(write(fd, cmd, len), -1);
602 	EXPECT_EQ(errno, EINVAL);
603 	close(fd);
604 
605 	EXPECT_FALSE(entry_shows("test_interp_bind",
606 				 "bpf-interpreter nul " BIND_FIRST));
607 }
608 
609 /* An entry binds at most BIND_MAX interpreters. */
610 TEST_F(bound_interp, capped_bindings)
611 {
612 	char name[16];
613 	int i;
614 
615 	/* The fixture bound "first" and "second" already. */
616 	for (i = 2; i < BIND_MAX; i++) {
617 		snprintf(name, sizeof(name), "n%d", i);
618 		ASSERT_EQ(entry_bind("test_interp_bind", name, BIND_FIRST), 0);
619 	}
620 	EXPECT_EQ(entry_bind("test_interp_bind", "over", BIND_FIRST), -ENOSPC);
621 }
622 
623 /* A binding pins a file: it is charged, and refused once the budget is out. */
624 TEST_F(bound_interp, bindings_are_charged)
625 {
626 	int err = bind_out_of_budget("test_interp_bind", "third", BIND_FIRST);
627 
628 	if (err < 0)
629 		SKIP(return, "no user namespaces or no " INTERP_LIMIT);
630 
631 	/* The charge follows the writer, not the entry file it writes to. */
632 	EXPECT_EQ(err, ENOSPC);
633 
634 	/* The budget was the only thing in the way. */
635 	EXPECT_EQ(entry_bind("test_interp_bind", "third", BIND_FIRST), 0);
636 }
637 
638 TEST_HARNESS_MAIN
639