1/* 2 * seccomp.c - seccomp utility functions 3 * Copyright (c) 2013 The Chromium Authors. All rights reserved. 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "config.h" 9 10#include <asm/unistd.h> 11#include <elf.h> 12#include <errno.h> 13#include <sys/prctl.h> 14#include <stddef.h> 15#include <stdint.h> 16#include <stdlib.h> 17#include <sys/syscall.h> 18#include <unistd.h> 19 20#include <linux/audit.h> 21#include <linux/filter.h> 22 23#include "src/seccomp.h" 24 25/* Linux seccomp_filter sandbox */ 26#define SECCOMP_FILTER_FAIL SECCOMP_RET_KILL 27 28/* Use a signal handler to emit violations when debugging */ 29#ifdef SECCOMP_FILTER_DEBUG 30# undef SECCOMP_FILTER_FAIL 31# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP 32#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 33 34/* Simple helpers to avoid manual errors (but larger BPF programs). */ 35#define SC_DENY(_nr, _errno) \ 36 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ 37 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(_errno)) 38#define SC_ALLOW(_nr) \ 39 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ 40 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) 41 42#if defined(__i386__) 43# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_I386 44#elif defined(__x86_64__) 45# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_X86_64 46#elif defined(__arm__) 47# ifndef EM_ARM 48# define EM_ARM 40 49# endif 50# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_ARM 51#elif defined(__aarch64__) 52# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_AARCH64 53#elif defined(__mips__) 54# if defined(__MIPSEL__) 55# if defined(__LP64__) 56# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_MIPSEL64 57# else 58# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_MIPSEL 59# endif 60# elif defined(__LP64__) 61# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_MIPS64 62# else 63# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_MIPS 64# endif 65#else 66# error "Platform does not support seccomp filter yet" 67#endif 68 69/* Returns 0 if the the sandbox is enabled using 70 * the time setter policy. 71 */ 72int 73enable_setter_seccomp (void) 74{ 75 static const struct sock_filter insns[] = 76 { 77 /* Ensure the syscall arch convention is as expected. */ 78 BPF_STMT (BPF_LD+BPF_W+BPF_ABS, 79 offsetof (struct seccomp_data, arch)), 80 BPF_JUMP (BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_AUDIT_ARCH, 1, 0), 81 BPF_STMT (BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), 82 /* Load the syscall number for checking. */ 83 BPF_STMT (BPF_LD+BPF_W+BPF_ABS, 84 offsetof (struct seccomp_data, nr)), 85 86 /* Process ALLOWs as quickly as possible */ 87 SC_ALLOW (read), 88 SC_ALLOW (write), 89 SC_ALLOW (pwrite64), 90 91 SC_ALLOW (settimeofday), 92 SC_ALLOW (ioctl), /* TODO(wad) filter for fd and RTC_SET_TIME */ 93#ifdef __NR_time /* This is required for x86 systems */ 94 SC_ALLOW (time), 95#endif 96 97#ifdef __NR_lseek 98 SC_ALLOW (lseek), 99#endif 100#ifdef __NR_llseek 101 SC_ALLOW (llseek), 102#endif 103#ifdef __NR_lseek64 104 SC_ALLOW (lseek64), 105#endif 106 SC_ALLOW (close), 107 SC_ALLOW (munmap), 108 109 SC_ALLOW (exit_group), 110 SC_ALLOW (exit), 111 112#ifdef __NR_open 113 SC_DENY (open, EINVAL), 114#endif 115#ifdef __NR_openat 116 SC_DENY (openat, EINVAL), 117#endif 118 SC_DENY (fcntl, EINVAL), 119#ifdef __NR_fstat 120 SC_DENY (fstat, EINVAL), 121#endif 122#ifdef __NR_fstatat 123 SC_DENY (fstatat, EINVAL), 124#endif 125#ifdef __NR_newfstatat 126 SC_DENY (newfstatat, EINVAL), 127#endif 128#ifdef __NR_mmap 129 SC_DENY (mmap, EINVAL), 130#endif 131#ifdef __NR_mmap2 132 SC_DENY (mmap2, EINVAL), 133#endif 134#ifdef __NR_sendto 135 SC_DENY (sendto, EINVAL), 136#endif 137#ifdef __NR_socket 138 SC_DENY (socket, EINVAL), 139#endif 140#ifdef __NR_socketcall 141 SC_DENY (socketcall, EINVAL), 142#endif 143 BPF_STMT (BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), 144 }; 145 static const struct sock_fprog prog = 146 { 147 .len = (unsigned short) (sizeof (insns) /sizeof (insns[0])), 148 .filter = (struct sock_filter *) insns, 149 }; 150 return (prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) || 151 prctl (PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)); 152} 153