xref: /linux/tools/testing/selftests/landlock/sandbox-and-launch.c (revision de5817bbfb569f22406970f81360ac3f694ba6e8)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Sandbox itself and execute another program (in a different mount point).
4  *
5  * Used by layout1.umount_sandboxer from fs_test.c
6  *
7  * Copyright © 2024-2025 Microsoft Corporation
8  */
9 
10 #define _GNU_SOURCE
11 #include <errno.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <sys/prctl.h>
15 #include <unistd.h>
16 
17 #include "wrappers.h"
18 
main(int argc,char * argv[])19 int main(int argc, char *argv[])
20 {
21 	struct landlock_ruleset_attr ruleset_attr = {
22 		.scoped = LANDLOCK_SCOPE_SIGNAL,
23 	};
24 	int pipe_child, pipe_parent, ruleset_fd;
25 	char buf;
26 
27 	/*
28 	 * The first argument must be the file descriptor number of a pipe.
29 	 * The second argument must be the program to execute.
30 	 */
31 	if (argc != 4) {
32 		fprintf(stderr, "Wrong number of arguments (not three)\n");
33 		return 1;
34 	}
35 
36 	pipe_child = atoi(argv[2]);
37 	pipe_parent = atoi(argv[3]);
38 
39 	ruleset_fd =
40 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
41 	if (ruleset_fd < 0) {
42 		perror("Failed to create ruleset");
43 		return 1;
44 	}
45 
46 	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
47 		perror("Failed to call prctl()");
48 		return 1;
49 	}
50 
51 	if (landlock_restrict_self(ruleset_fd, 0)) {
52 		perror("Failed to restrict self");
53 		return 1;
54 	}
55 
56 	if (close(ruleset_fd)) {
57 		perror("Failed to close ruleset");
58 		return 1;
59 	}
60 
61 	/* Signals that we are sandboxed. */
62 	errno = 0;
63 	if (write(pipe_child, ".", 1) != 1) {
64 		perror("Failed to write to the second argument");
65 		return 1;
66 	}
67 
68 	/* Waits for the parent to try to umount. */
69 	if (read(pipe_parent, &buf, 1) != 1) {
70 		perror("Failed to write to the third argument");
71 		return 1;
72 	}
73 
74 	/* Shifts arguments. */
75 	argv[0] = argv[1];
76 	argv[1] = argv[2];
77 	argv[2] = argv[3];
78 	argv[3] = NULL;
79 	execve(argv[0], argv, NULL);
80 	perror("Failed to execute the provided binary");
81 	return 1;
82 }
83