forked from mirrors/linux
		
	 faf2d88e55
			
		
	
	
		faf2d88e55
		
	
	
	
	
		
			
			Add a simple tool to set SECBIT_EXEC_RESTRICT_FILE or SECBIT_EXEC_DENY_INTERACTIVE before executing a command. This is useful to easily test against enlighten script interpreters. Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christian Brauner <brauner@kernel.org> Cc: Kees Cook <keescook@chromium.org> Cc: Paul Moore <paul@paul-moore.com> Cc: Serge Hallyn <serge@hallyn.com> Signed-off-by: Mickaël Salaün <mic@digikod.net> Link: https://lore.kernel.org/r/20241212174223.389435-6-mic@digikod.net Signed-off-by: Kees Cook <kees@kernel.org>
		
			
				
	
	
		
			85 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: BSD-3-Clause
 | |
| /*
 | |
|  * Simple tool to set SECBIT_EXEC_RESTRICT_FILE, SECBIT_EXEC_DENY_INTERACTIVE,
 | |
|  * before executing a command.
 | |
|  *
 | |
|  * Copyright © 2024 Microsoft Corporation
 | |
|  */
 | |
| 
 | |
| #define _GNU_SOURCE
 | |
| #define __SANE_USERSPACE_TYPES__
 | |
| #include <errno.h>
 | |
| #include <linux/prctl.h>
 | |
| #include <linux/securebits.h>
 | |
| #include <stdbool.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <sys/prctl.h>
 | |
| #include <unistd.h>
 | |
| 
 | |
| static void print_usage(const char *argv0)
 | |
| {
 | |
| 	fprintf(stderr, "usage: %s -f|-i -- <cmd> [args]...\n\n", argv0);
 | |
| 	fprintf(stderr, "Execute a command with\n");
 | |
| 	fprintf(stderr, "- SECBIT_EXEC_RESTRICT_FILE set: -f\n");
 | |
| 	fprintf(stderr, "- SECBIT_EXEC_DENY_INTERACTIVE set: -i\n");
 | |
| }
 | |
| 
 | |
| int main(const int argc, char *const argv[], char *const *const envp)
 | |
| {
 | |
| 	const char *cmd_path;
 | |
| 	char *const *cmd_argv;
 | |
| 	int opt, secbits_cur, secbits_new;
 | |
| 	bool has_policy = false;
 | |
| 
 | |
| 	secbits_cur = prctl(PR_GET_SECUREBITS);
 | |
| 	if (secbits_cur == -1) {
 | |
| 		/*
 | |
| 		 * This should never happen, except with a buggy seccomp
 | |
| 		 * filter.
 | |
| 		 */
 | |
| 		perror("ERROR: Failed to get securebits");
 | |
| 		return 1;
 | |
| 	}
 | |
| 
 | |
| 	secbits_new = secbits_cur;
 | |
| 	while ((opt = getopt(argc, argv, "fi")) != -1) {
 | |
| 		switch (opt) {
 | |
| 		case 'f':
 | |
| 			secbits_new |= SECBIT_EXEC_RESTRICT_FILE |
 | |
| 				       SECBIT_EXEC_RESTRICT_FILE_LOCKED;
 | |
| 			has_policy = true;
 | |
| 			break;
 | |
| 		case 'i':
 | |
| 			secbits_new |= SECBIT_EXEC_DENY_INTERACTIVE |
 | |
| 				       SECBIT_EXEC_DENY_INTERACTIVE_LOCKED;
 | |
| 			has_policy = true;
 | |
| 			break;
 | |
| 		default:
 | |
| 			print_usage(argv[0]);
 | |
| 			return 1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if (!argv[optind] || !has_policy) {
 | |
| 		print_usage(argv[0]);
 | |
| 		return 1;
 | |
| 	}
 | |
| 
 | |
| 	if (secbits_cur != secbits_new &&
 | |
| 	    prctl(PR_SET_SECUREBITS, secbits_new)) {
 | |
| 		perror("Failed to set secure bit(s).");
 | |
| 		fprintf(stderr,
 | |
| 			"Hint: The running kernel may not support this feature.\n");
 | |
| 		return 1;
 | |
| 	}
 | |
| 
 | |
| 	cmd_path = argv[optind];
 | |
| 	cmd_argv = argv + optind;
 | |
| 	fprintf(stderr, "Executing command...\n");
 | |
| 	execvpe(cmd_path, cmd_argv, envp);
 | |
| 	fprintf(stderr, "Failed to execute \"%s\": %s\n", cmd_path,
 | |
| 		strerror(errno));
 | |
| 	return 1;
 | |
| }
 |