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 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