qemu/qemu-seccomp.c
<<
>>
Prefs
   1/*
   2 * QEMU seccomp mode 2 support with libseccomp
   3 *
   4 * Copyright IBM, Corp. 2012
   5 *
   6 * Authors:
   7 *  Eduardo Otubo    <eotubo@br.ibm.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2.  See
  10 * the COPYING file in the top-level directory.
  11 *
  12 * Contributions after 2012-01-13 are licensed under the terms of the
  13 * GNU GPL, version 2 or (at your option) any later version.
  14 */
  15#include "qemu/osdep.h"
  16#include <seccomp.h>
  17#include "sysemu/seccomp.h"
  18
  19/* For some architectures (notably ARM) cacheflush is not supported until
  20 * libseccomp 2.2.3, but configure enforces that we are using a more recent
  21 * version on those hosts, so it is OK for this check to be less strict.
  22 */
  23#if SCMP_VER_MAJOR >= 3
  24  #define HAVE_CACHEFLUSH
  25#elif SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR >= 2
  26  #define HAVE_CACHEFLUSH
  27#endif
  28
  29struct QemuSeccompSyscall {
  30    int32_t num;
  31    uint8_t priority;
  32};
  33
  34static const struct QemuSeccompSyscall seccomp_whitelist[] = {
  35    { SCMP_SYS(timer_settime), 255 },
  36    { SCMP_SYS(timer_gettime), 254 },
  37    { SCMP_SYS(futex), 253 },
  38    { SCMP_SYS(select), 252 },
  39    { SCMP_SYS(recvfrom), 251 },
  40    { SCMP_SYS(sendto), 250 },
  41    { SCMP_SYS(socketcall), 250 },
  42    { SCMP_SYS(read), 249 },
  43    { SCMP_SYS(io_submit), 249 },
  44    { SCMP_SYS(brk), 248 },
  45    { SCMP_SYS(clone), 247 },
  46    { SCMP_SYS(mmap), 247 },
  47    { SCMP_SYS(mprotect), 246 },
  48    { SCMP_SYS(execve), 245 },
  49    { SCMP_SYS(open), 245 },
  50    { SCMP_SYS(ioctl), 245 },
  51    { SCMP_SYS(socket), 245 },
  52    { SCMP_SYS(setsockopt), 245 },
  53    { SCMP_SYS(recvmsg), 245 },
  54    { SCMP_SYS(sendmsg), 245 },
  55    { SCMP_SYS(accept), 245 },
  56    { SCMP_SYS(connect), 245 },
  57    { SCMP_SYS(socketpair), 245 },
  58    { SCMP_SYS(bind), 245 },
  59    { SCMP_SYS(listen), 245 },
  60    { SCMP_SYS(semget), 245 },
  61    { SCMP_SYS(ipc), 245 },
  62    { SCMP_SYS(gettimeofday), 245 },
  63    { SCMP_SYS(readlink), 245 },
  64    { SCMP_SYS(access), 245 },
  65    { SCMP_SYS(prctl), 245 },
  66    { SCMP_SYS(signalfd), 245 },
  67    { SCMP_SYS(getrlimit), 245 },
  68    { SCMP_SYS(set_tid_address), 245 },
  69    { SCMP_SYS(statfs), 245 },
  70    { SCMP_SYS(unlink), 245 },
  71    { SCMP_SYS(wait4), 245 },
  72    { SCMP_SYS(fcntl64), 245 },
  73    { SCMP_SYS(fstat64), 245 },
  74    { SCMP_SYS(stat64), 245 },
  75    { SCMP_SYS(getgid32), 245 },
  76    { SCMP_SYS(getegid32), 245 },
  77    { SCMP_SYS(getuid32), 245 },
  78    { SCMP_SYS(geteuid32), 245 },
  79    { SCMP_SYS(sigreturn), 245 },
  80    { SCMP_SYS(_newselect), 245 },
  81    { SCMP_SYS(_llseek), 245 },
  82    { SCMP_SYS(mmap2), 245 },
  83    { SCMP_SYS(sigprocmask), 245 },
  84    { SCMP_SYS(sched_getparam), 245 },
  85    { SCMP_SYS(sched_getscheduler), 245 },
  86    { SCMP_SYS(fstat), 245 },
  87    { SCMP_SYS(clock_getres), 245 },
  88    { SCMP_SYS(sched_get_priority_min), 245 },
  89    { SCMP_SYS(sched_get_priority_max), 245 },
  90    { SCMP_SYS(stat), 245 },
  91    { SCMP_SYS(uname), 245 },
  92    { SCMP_SYS(eventfd2), 245 },
  93    { SCMP_SYS(io_getevents), 245 },
  94    { SCMP_SYS(dup), 245 },
  95    { SCMP_SYS(dup2), 245 },
  96    { SCMP_SYS(dup3), 245 },
  97    { SCMP_SYS(gettid), 245 },
  98    { SCMP_SYS(getgid), 245 },
  99    { SCMP_SYS(getegid), 245 },
 100    { SCMP_SYS(getuid), 245 },
 101    { SCMP_SYS(geteuid), 245 },
 102    { SCMP_SYS(timer_create), 245 },
 103    { SCMP_SYS(times), 245 },
 104    { SCMP_SYS(exit), 245 },
 105    { SCMP_SYS(clock_gettime), 245 },
 106    { SCMP_SYS(time), 245 },
 107    { SCMP_SYS(restart_syscall), 245 },
 108    { SCMP_SYS(pwrite64), 245 },
 109    { SCMP_SYS(nanosleep), 245 },
 110    { SCMP_SYS(chown), 245 },
 111    { SCMP_SYS(openat), 245 },
 112    { SCMP_SYS(getdents), 245 },
 113    { SCMP_SYS(timer_delete), 245 },
 114    { SCMP_SYS(exit_group), 245 },
 115    { SCMP_SYS(rt_sigreturn), 245 },
 116    { SCMP_SYS(sync), 245 },
 117    { SCMP_SYS(pread64), 245 },
 118    { SCMP_SYS(madvise), 245 },
 119    { SCMP_SYS(set_robust_list), 245 },
 120    { SCMP_SYS(lseek), 245 },
 121    { SCMP_SYS(pselect6), 245 },
 122    { SCMP_SYS(fork), 245 },
 123    { SCMP_SYS(rt_sigprocmask), 245 },
 124    { SCMP_SYS(write), 244 },
 125    { SCMP_SYS(fcntl), 243 },
 126    { SCMP_SYS(tgkill), 242 },
 127    { SCMP_SYS(kill), 242 },
 128    { SCMP_SYS(rt_sigaction), 242 },
 129    { SCMP_SYS(pipe2), 242 },
 130    { SCMP_SYS(munmap), 242 },
 131    { SCMP_SYS(mremap), 242 },
 132    { SCMP_SYS(fdatasync), 242 },
 133    { SCMP_SYS(close), 242 },
 134    { SCMP_SYS(rt_sigpending), 242 },
 135    { SCMP_SYS(rt_sigtimedwait), 242 },
 136    { SCMP_SYS(readv), 242 },
 137    { SCMP_SYS(writev), 242 },
 138    { SCMP_SYS(preadv), 242 },
 139    { SCMP_SYS(pwritev), 242 },
 140    { SCMP_SYS(setrlimit), 242 },
 141    { SCMP_SYS(ftruncate), 242 },
 142    { SCMP_SYS(lstat), 242 },
 143    { SCMP_SYS(pipe), 242 },
 144    { SCMP_SYS(umask), 242 },
 145    { SCMP_SYS(chdir), 242 },
 146    { SCMP_SYS(setitimer), 242 },
 147    { SCMP_SYS(setsid), 242 },
 148    { SCMP_SYS(poll), 242 },
 149    { SCMP_SYS(epoll_create), 242 },
 150    { SCMP_SYS(epoll_ctl), 242 },
 151    { SCMP_SYS(epoll_wait), 242 },
 152    { SCMP_SYS(waitpid), 242 },
 153    { SCMP_SYS(getsockname), 242 },
 154    { SCMP_SYS(getpeername), 242 },
 155    { SCMP_SYS(accept4), 242 },
 156    { SCMP_SYS(timerfd_settime), 242 },
 157    { SCMP_SYS(newfstatat), 241 },
 158    { SCMP_SYS(shutdown), 241 },
 159    { SCMP_SYS(getsockopt), 241 },
 160    { SCMP_SYS(semop), 241 },
 161    { SCMP_SYS(semtimedop), 241 },
 162    { SCMP_SYS(epoll_ctl_old), 241 },
 163    { SCMP_SYS(epoll_wait_old), 241 },
 164    { SCMP_SYS(epoll_pwait), 241 },
 165    { SCMP_SYS(epoll_create1), 241 },
 166    { SCMP_SYS(ppoll), 241 },
 167    { SCMP_SYS(creat), 241 },
 168    { SCMP_SYS(link), 241 },
 169    { SCMP_SYS(getpid), 241 },
 170    { SCMP_SYS(getppid), 241 },
 171    { SCMP_SYS(getpgrp), 241 },
 172    { SCMP_SYS(getpgid), 241 },
 173    { SCMP_SYS(getsid), 241 },
 174    { SCMP_SYS(getdents64), 241 },
 175    { SCMP_SYS(getresuid), 241 },
 176    { SCMP_SYS(getresgid), 241 },
 177    { SCMP_SYS(getgroups), 241 },
 178    { SCMP_SYS(getresuid32), 241 },
 179    { SCMP_SYS(getresgid32), 241 },
 180    { SCMP_SYS(getgroups32), 241 },
 181    { SCMP_SYS(signal), 241 },
 182    { SCMP_SYS(sigaction), 241 },
 183    { SCMP_SYS(sigsuspend), 241 },
 184    { SCMP_SYS(sigpending), 241 },
 185    { SCMP_SYS(truncate64), 241 },
 186    { SCMP_SYS(ftruncate64), 241 },
 187    { SCMP_SYS(fchown32), 241 },
 188    { SCMP_SYS(chown32), 241 },
 189    { SCMP_SYS(lchown32), 241 },
 190    { SCMP_SYS(statfs64), 241 },
 191    { SCMP_SYS(fstatfs64), 241 },
 192    { SCMP_SYS(fstatat64), 241 },
 193    { SCMP_SYS(lstat64), 241 },
 194    { SCMP_SYS(sendfile64), 241 },
 195    { SCMP_SYS(ugetrlimit), 241 },
 196    { SCMP_SYS(alarm), 241 },
 197    { SCMP_SYS(rt_sigsuspend), 241 },
 198    { SCMP_SYS(rt_sigqueueinfo), 241 },
 199    { SCMP_SYS(rt_tgsigqueueinfo), 241 },
 200    { SCMP_SYS(sigaltstack), 241 },
 201    { SCMP_SYS(signalfd4), 241 },
 202    { SCMP_SYS(truncate), 241 },
 203    { SCMP_SYS(fchown), 241 },
 204    { SCMP_SYS(lchown), 241 },
 205    { SCMP_SYS(fchownat), 241 },
 206    { SCMP_SYS(fstatfs), 241 },
 207    { SCMP_SYS(getitimer), 241 },
 208    { SCMP_SYS(syncfs), 241 },
 209    { SCMP_SYS(fsync), 241 },
 210    { SCMP_SYS(fchdir), 241 },
 211    { SCMP_SYS(msync), 241 },
 212    { SCMP_SYS(sched_setparam), 241 },
 213    { SCMP_SYS(sched_setscheduler), 241 },
 214    { SCMP_SYS(sched_yield), 241 },
 215    { SCMP_SYS(sched_rr_get_interval), 241 },
 216    { SCMP_SYS(sched_setaffinity), 241 },
 217    { SCMP_SYS(sched_getaffinity), 241 },
 218    { SCMP_SYS(readahead), 241 },
 219    { SCMP_SYS(timer_getoverrun), 241 },
 220    { SCMP_SYS(unlinkat), 241 },
 221    { SCMP_SYS(readlinkat), 241 },
 222    { SCMP_SYS(faccessat), 241 },
 223    { SCMP_SYS(get_robust_list), 241 },
 224    { SCMP_SYS(splice), 241 },
 225    { SCMP_SYS(vmsplice), 241 },
 226    { SCMP_SYS(getcpu), 241 },
 227    { SCMP_SYS(sendmmsg), 241 },
 228    { SCMP_SYS(recvmmsg), 241 },
 229    { SCMP_SYS(prlimit64), 241 },
 230    { SCMP_SYS(waitid), 241 },
 231    { SCMP_SYS(io_cancel), 241 },
 232    { SCMP_SYS(io_setup), 241 },
 233    { SCMP_SYS(io_destroy), 241 },
 234    { SCMP_SYS(arch_prctl), 240 },
 235    { SCMP_SYS(mkdir), 240 },
 236    { SCMP_SYS(fchmod), 240 },
 237    { SCMP_SYS(shmget), 240 },
 238    { SCMP_SYS(shmat), 240 },
 239    { SCMP_SYS(shmdt), 240 },
 240    { SCMP_SYS(timerfd_create), 240 },
 241    { SCMP_SYS(shmctl), 240 },
 242    { SCMP_SYS(mlockall), 240 },
 243    { SCMP_SYS(mlock), 240 },
 244    { SCMP_SYS(munlock), 240 },
 245    { SCMP_SYS(semctl), 240 },
 246    { SCMP_SYS(fallocate), 240 },
 247    { SCMP_SYS(fadvise64), 240 },
 248    { SCMP_SYS(inotify_init1), 240 },
 249    { SCMP_SYS(inotify_add_watch), 240 },
 250    { SCMP_SYS(mbind), 240 },
 251    { SCMP_SYS(memfd_create), 240 },
 252#ifdef HAVE_CACHEFLUSH
 253    { SCMP_SYS(cacheflush), 240 },
 254#endif
 255    { SCMP_SYS(sysinfo), 240 },
 256};
 257
 258int seccomp_start(void)
 259{
 260    int rc = 0;
 261    unsigned int i = 0;
 262    scmp_filter_ctx ctx;
 263
 264    ctx = seccomp_init(SCMP_ACT_KILL);
 265    if (ctx == NULL) {
 266        rc = -1;
 267        goto seccomp_return;
 268    }
 269
 270    for (i = 0; i < ARRAY_SIZE(seccomp_whitelist); i++) {
 271        rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, seccomp_whitelist[i].num, 0);
 272        if (rc < 0) {
 273            goto seccomp_return;
 274        }
 275        rc = seccomp_syscall_priority(ctx, seccomp_whitelist[i].num,
 276                                      seccomp_whitelist[i].priority);
 277        if (rc < 0) {
 278            goto seccomp_return;
 279        }
 280    }
 281
 282    rc = seccomp_load(ctx);
 283
 284  seccomp_return:
 285    seccomp_release(ctx);
 286    return rc;
 287}
 288