18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Seccomp BPF example using a macro-based generator. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org> 68c2ecf20Sopenharmony_ci * Author: Will Drewry <wad@chromium.org> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * The code may be used by anyone for any purpose, 98c2ecf20Sopenharmony_ci * and can serve as a starting point for developing 108c2ecf20Sopenharmony_ci * applications using prctl(PR_ATTACH_SECCOMP_FILTER). 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/filter.h> 148c2ecf20Sopenharmony_ci#include <linux/seccomp.h> 158c2ecf20Sopenharmony_ci#include <linux/unistd.h> 168c2ecf20Sopenharmony_ci#include <stdio.h> 178c2ecf20Sopenharmony_ci#include <string.h> 188c2ecf20Sopenharmony_ci#include <sys/prctl.h> 198c2ecf20Sopenharmony_ci#include <unistd.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include "bpf-helper.h" 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#ifndef PR_SET_NO_NEW_PRIVS 248c2ecf20Sopenharmony_ci#define PR_SET_NO_NEW_PRIVS 38 258c2ecf20Sopenharmony_ci#endif 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ciint main(int argc, char **argv) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci struct bpf_labels l = { 308c2ecf20Sopenharmony_ci .count = 0, 318c2ecf20Sopenharmony_ci }; 328c2ecf20Sopenharmony_ci static const char msg1[] = "Please type something: "; 338c2ecf20Sopenharmony_ci static const char msg2[] = "You typed: "; 348c2ecf20Sopenharmony_ci char buf[256]; 358c2ecf20Sopenharmony_ci struct sock_filter filter[] = { 368c2ecf20Sopenharmony_ci /* TODO: LOAD_SYSCALL_NR(arch) and enforce an arch */ 378c2ecf20Sopenharmony_ci LOAD_SYSCALL_NR, 388c2ecf20Sopenharmony_ci SYSCALL(__NR_exit, ALLOW), 398c2ecf20Sopenharmony_ci SYSCALL(__NR_exit_group, ALLOW), 408c2ecf20Sopenharmony_ci SYSCALL(__NR_write, JUMP(&l, write_fd)), 418c2ecf20Sopenharmony_ci SYSCALL(__NR_read, JUMP(&l, read)), 428c2ecf20Sopenharmony_ci DENY, /* Don't passthrough into a label */ 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci LABEL(&l, read), 458c2ecf20Sopenharmony_ci ARG(0), 468c2ecf20Sopenharmony_ci JNE(STDIN_FILENO, DENY), 478c2ecf20Sopenharmony_ci ARG(1), 488c2ecf20Sopenharmony_ci JNE((unsigned long)buf, DENY), 498c2ecf20Sopenharmony_ci ARG(2), 508c2ecf20Sopenharmony_ci JGE(sizeof(buf), DENY), 518c2ecf20Sopenharmony_ci ALLOW, 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci LABEL(&l, write_fd), 548c2ecf20Sopenharmony_ci ARG(0), 558c2ecf20Sopenharmony_ci JEQ(STDOUT_FILENO, JUMP(&l, write_buf)), 568c2ecf20Sopenharmony_ci JEQ(STDERR_FILENO, JUMP(&l, write_buf)), 578c2ecf20Sopenharmony_ci DENY, 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci LABEL(&l, write_buf), 608c2ecf20Sopenharmony_ci ARG(1), 618c2ecf20Sopenharmony_ci JEQ((unsigned long)msg1, JUMP(&l, msg1_len)), 628c2ecf20Sopenharmony_ci JEQ((unsigned long)msg2, JUMP(&l, msg2_len)), 638c2ecf20Sopenharmony_ci JEQ((unsigned long)buf, JUMP(&l, buf_len)), 648c2ecf20Sopenharmony_ci DENY, 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci LABEL(&l, msg1_len), 678c2ecf20Sopenharmony_ci ARG(2), 688c2ecf20Sopenharmony_ci JLT(sizeof(msg1), ALLOW), 698c2ecf20Sopenharmony_ci DENY, 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci LABEL(&l, msg2_len), 728c2ecf20Sopenharmony_ci ARG(2), 738c2ecf20Sopenharmony_ci JLT(sizeof(msg2), ALLOW), 748c2ecf20Sopenharmony_ci DENY, 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci LABEL(&l, buf_len), 778c2ecf20Sopenharmony_ci ARG(2), 788c2ecf20Sopenharmony_ci JLT(sizeof(buf), ALLOW), 798c2ecf20Sopenharmony_ci DENY, 808c2ecf20Sopenharmony_ci }; 818c2ecf20Sopenharmony_ci struct sock_fprog prog = { 828c2ecf20Sopenharmony_ci .filter = filter, 838c2ecf20Sopenharmony_ci .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])), 848c2ecf20Sopenharmony_ci }; 858c2ecf20Sopenharmony_ci ssize_t bytes; 868c2ecf20Sopenharmony_ci bpf_resolve_jumps(&l, filter, sizeof(filter)/sizeof(*filter)); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { 898c2ecf20Sopenharmony_ci perror("prctl(NO_NEW_PRIVS)"); 908c2ecf20Sopenharmony_ci return 1; 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { 948c2ecf20Sopenharmony_ci perror("prctl(SECCOMP)"); 958c2ecf20Sopenharmony_ci return 1; 968c2ecf20Sopenharmony_ci } 978c2ecf20Sopenharmony_ci syscall(__NR_write, STDOUT_FILENO, msg1, strlen(msg1)); 988c2ecf20Sopenharmony_ci bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf)-1); 998c2ecf20Sopenharmony_ci bytes = (bytes > 0 ? bytes : 0); 1008c2ecf20Sopenharmony_ci syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2)); 1018c2ecf20Sopenharmony_ci syscall(__NR_write, STDERR_FILENO, buf, bytes); 1028c2ecf20Sopenharmony_ci /* Now get killed */ 1038c2ecf20Sopenharmony_ci syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2)+2); 1048c2ecf20Sopenharmony_ci return 0; 1058c2ecf20Sopenharmony_ci} 106