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