brintos

brintos / linux-shallow public Read only

0
0
Text · 2.1 KiB · 4bca4b7 Raw
78 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Naive system call dropper built on seccomp_filter.4 *5 * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>6 * Author: Will Drewry <wad@chromium.org>7 *8 * The code may be used by anyone for any purpose,9 * and can serve as a starting point for developing10 * applications using prctl(PR_SET_SECCOMP, 2, ...).11 *12 * When run, returns the specified errno for the specified13 * system call number against the given architecture.14 *15 */16 17#include <errno.h>18#include <linux/audit.h>19#include <linux/filter.h>20#include <linux/seccomp.h>21#include <linux/unistd.h>22#include <stdio.h>23#include <stddef.h>24#include <stdlib.h>25#include <sys/prctl.h>26#include <unistd.h>27 28static int install_filter(int arch, int nr, int error)29{30	struct sock_filter filter[] = {31		BPF_STMT(BPF_LD+BPF_W+BPF_ABS,32			 (offsetof(struct seccomp_data, arch))),33		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, arch, 0, 3),34		BPF_STMT(BPF_LD+BPF_W+BPF_ABS,35			 (offsetof(struct seccomp_data, nr))),36		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, nr, 0, 1),37		BPF_STMT(BPF_RET+BPF_K,38			 SECCOMP_RET_ERRNO|(error & SECCOMP_RET_DATA)),39		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),40	};41	struct sock_fprog prog = {42		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),43		.filter = filter,44	};45	if (error == -1) {46		struct sock_filter kill = BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL);47		filter[4] = kill;48	}49	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {50		perror("prctl(NO_NEW_PRIVS)");51		return 1;52	}53	if (prctl(PR_SET_SECCOMP, 2, &prog)) {54		perror("prctl(PR_SET_SECCOMP)");55		return 1;56	}57	return 0;58}59 60int main(int argc, char **argv)61{62	if (argc < 5) {63		fprintf(stderr, "Usage:\n"64			"dropper <arch> <syscall_nr> <errno> <prog> [<args>]\n"65			"Hint:	AUDIT_ARCH_I386: 0x%X\n"66			"	AUDIT_ARCH_X86_64: 0x%X\n"67			"	errno == -1 means SECCOMP_RET_KILL\n"68			"\n", AUDIT_ARCH_I386, AUDIT_ARCH_X86_64);69		return 1;70	}71	if (install_filter(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0),72			   strtol(argv[3], NULL, 0)))73		return 1;74	execv(argv[4], &argv[4]);75	printf("Failed to execv\n");76	return 255;77}78