162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Seccomp BPF example using a macro-based generator. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org> 662306a36Sopenharmony_ci * Author: Will Drewry <wad@chromium.org> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * The code may be used by anyone for any purpose, 962306a36Sopenharmony_ci * and can serve as a starting point for developing 1062306a36Sopenharmony_ci * applications using prctl(PR_ATTACH_SECCOMP_FILTER). 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/filter.h> 1462306a36Sopenharmony_ci#include <linux/seccomp.h> 1562306a36Sopenharmony_ci#include <linux/unistd.h> 1662306a36Sopenharmony_ci#include <stdio.h> 1762306a36Sopenharmony_ci#include <string.h> 1862306a36Sopenharmony_ci#include <sys/prctl.h> 1962306a36Sopenharmony_ci#include <unistd.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include "bpf-helper.h" 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#ifndef PR_SET_NO_NEW_PRIVS 2462306a36Sopenharmony_ci#define PR_SET_NO_NEW_PRIVS 38 2562306a36Sopenharmony_ci#endif 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ciint main(int argc, char **argv) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci struct bpf_labels l = { 3062306a36Sopenharmony_ci .count = 0, 3162306a36Sopenharmony_ci }; 3262306a36Sopenharmony_ci static const char msg1[] = "Please type something: "; 3362306a36Sopenharmony_ci static const char msg2[] = "You typed: "; 3462306a36Sopenharmony_ci char buf[256]; 3562306a36Sopenharmony_ci struct sock_filter filter[] = { 3662306a36Sopenharmony_ci /* TODO: LOAD_SYSCALL_NR(arch) and enforce an arch */ 3762306a36Sopenharmony_ci LOAD_SYSCALL_NR, 3862306a36Sopenharmony_ci SYSCALL(__NR_exit, ALLOW), 3962306a36Sopenharmony_ci SYSCALL(__NR_exit_group, ALLOW), 4062306a36Sopenharmony_ci SYSCALL(__NR_write, JUMP(&l, write_fd)), 4162306a36Sopenharmony_ci SYSCALL(__NR_read, JUMP(&l, read)), 4262306a36Sopenharmony_ci DENY, /* Don't passthrough into a label */ 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci LABEL(&l, read), 4562306a36Sopenharmony_ci ARG(0), 4662306a36Sopenharmony_ci JNE(STDIN_FILENO, DENY), 4762306a36Sopenharmony_ci ARG(1), 4862306a36Sopenharmony_ci JNE((unsigned long)buf, DENY), 4962306a36Sopenharmony_ci ARG(2), 5062306a36Sopenharmony_ci JGE(sizeof(buf), DENY), 5162306a36Sopenharmony_ci ALLOW, 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci LABEL(&l, write_fd), 5462306a36Sopenharmony_ci ARG(0), 5562306a36Sopenharmony_ci JEQ(STDOUT_FILENO, JUMP(&l, write_buf)), 5662306a36Sopenharmony_ci JEQ(STDERR_FILENO, JUMP(&l, write_buf)), 5762306a36Sopenharmony_ci DENY, 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci LABEL(&l, write_buf), 6062306a36Sopenharmony_ci ARG(1), 6162306a36Sopenharmony_ci JEQ((unsigned long)msg1, JUMP(&l, msg1_len)), 6262306a36Sopenharmony_ci JEQ((unsigned long)msg2, JUMP(&l, msg2_len)), 6362306a36Sopenharmony_ci JEQ((unsigned long)buf, JUMP(&l, buf_len)), 6462306a36Sopenharmony_ci DENY, 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci LABEL(&l, msg1_len), 6762306a36Sopenharmony_ci ARG(2), 6862306a36Sopenharmony_ci JLT(sizeof(msg1), ALLOW), 6962306a36Sopenharmony_ci DENY, 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci LABEL(&l, msg2_len), 7262306a36Sopenharmony_ci ARG(2), 7362306a36Sopenharmony_ci JLT(sizeof(msg2), ALLOW), 7462306a36Sopenharmony_ci DENY, 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci LABEL(&l, buf_len), 7762306a36Sopenharmony_ci ARG(2), 7862306a36Sopenharmony_ci JLT(sizeof(buf), ALLOW), 7962306a36Sopenharmony_ci DENY, 8062306a36Sopenharmony_ci }; 8162306a36Sopenharmony_ci struct sock_fprog prog = { 8262306a36Sopenharmony_ci .filter = filter, 8362306a36Sopenharmony_ci .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])), 8462306a36Sopenharmony_ci }; 8562306a36Sopenharmony_ci ssize_t bytes; 8662306a36Sopenharmony_ci bpf_resolve_jumps(&l, filter, sizeof(filter)/sizeof(*filter)); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { 8962306a36Sopenharmony_ci perror("prctl(NO_NEW_PRIVS)"); 9062306a36Sopenharmony_ci return 1; 9162306a36Sopenharmony_ci } 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { 9462306a36Sopenharmony_ci perror("prctl(SECCOMP)"); 9562306a36Sopenharmony_ci return 1; 9662306a36Sopenharmony_ci } 9762306a36Sopenharmony_ci syscall(__NR_write, STDOUT_FILENO, msg1, strlen(msg1)); 9862306a36Sopenharmony_ci bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf)-1); 9962306a36Sopenharmony_ci bytes = (bytes > 0 ? bytes : 0); 10062306a36Sopenharmony_ci syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2)); 10162306a36Sopenharmony_ci syscall(__NR_write, STDERR_FILENO, buf, bytes); 10262306a36Sopenharmony_ci /* Now get killed */ 10362306a36Sopenharmony_ci syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2)+2); 10462306a36Sopenharmony_ci return 0; 10562306a36Sopenharmony_ci} 106