85 lines · 2.0 KB · C
RawDownload
// 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;}