cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

passthrough_seccomp.c (4399B)


      1/*
      2 * Seccomp sandboxing for virtiofsd
      3 *
      4 * Copyright (C) 2019 Red Hat, Inc.
      5 *
      6 * SPDX-License-Identifier: GPL-2.0-or-later
      7 */
      8
      9#include "qemu/osdep.h"
     10#include "passthrough_seccomp.h"
     11#include "fuse_i.h"
     12#include "fuse_log.h"
     13#include <seccomp.h>
     14
     15/* Bodge for libseccomp 2.4.2 which broke ppoll */
     16#if !defined(__SNR_ppoll) && defined(__SNR_brk)
     17#ifdef __NR_ppoll
     18#define __SNR_ppoll __NR_ppoll
     19#else
     20#define __SNR_ppoll __PNR_ppoll
     21#endif
     22#endif
     23
     24static const int syscall_allowlist[] = {
     25    /* TODO ireg sem*() syscalls */
     26    SCMP_SYS(brk),
     27    SCMP_SYS(capget), /* For CAP_FSETID */
     28    SCMP_SYS(capset),
     29    SCMP_SYS(clock_gettime),
     30    SCMP_SYS(clone),
     31#ifdef __NR_clone3
     32    SCMP_SYS(clone3),
     33#endif
     34    SCMP_SYS(close),
     35    SCMP_SYS(copy_file_range),
     36    SCMP_SYS(dup),
     37    SCMP_SYS(eventfd2),
     38    SCMP_SYS(exit),
     39    SCMP_SYS(exit_group),
     40    SCMP_SYS(fallocate),
     41    SCMP_SYS(fchdir),
     42    SCMP_SYS(fchmod),
     43    SCMP_SYS(fchmodat),
     44    SCMP_SYS(fchownat),
     45    SCMP_SYS(fcntl),
     46    SCMP_SYS(fdatasync),
     47    SCMP_SYS(fgetxattr),
     48    SCMP_SYS(flistxattr),
     49    SCMP_SYS(flock),
     50    SCMP_SYS(fremovexattr),
     51    SCMP_SYS(fsetxattr),
     52    SCMP_SYS(fstat),
     53    SCMP_SYS(fstatfs),
     54    SCMP_SYS(fstatfs64),
     55    SCMP_SYS(fsync),
     56    SCMP_SYS(ftruncate),
     57    SCMP_SYS(futex),
     58    SCMP_SYS(getdents),
     59    SCMP_SYS(getdents64),
     60    SCMP_SYS(getegid),
     61    SCMP_SYS(geteuid),
     62    SCMP_SYS(getpid),
     63    SCMP_SYS(gettid),
     64    SCMP_SYS(gettimeofday),
     65    SCMP_SYS(getxattr),
     66    SCMP_SYS(linkat),
     67    SCMP_SYS(listxattr),
     68    SCMP_SYS(lseek),
     69    SCMP_SYS(_llseek), /* For POWER */
     70    SCMP_SYS(madvise),
     71    SCMP_SYS(mkdirat),
     72    SCMP_SYS(mknodat),
     73    SCMP_SYS(mmap),
     74    SCMP_SYS(mprotect),
     75    SCMP_SYS(mremap),
     76    SCMP_SYS(munmap),
     77    SCMP_SYS(newfstatat),
     78    SCMP_SYS(statx),
     79    SCMP_SYS(open),
     80    SCMP_SYS(openat),
     81    SCMP_SYS(ppoll),
     82    SCMP_SYS(prctl), /* TODO restrict to just PR_SET_NAME? */
     83    SCMP_SYS(preadv),
     84    SCMP_SYS(pread64),
     85    SCMP_SYS(pwritev),
     86    SCMP_SYS(pwrite64),
     87    SCMP_SYS(read),
     88    SCMP_SYS(readlinkat),
     89    SCMP_SYS(recvmsg),
     90    SCMP_SYS(renameat),
     91    SCMP_SYS(renameat2),
     92    SCMP_SYS(removexattr),
     93    SCMP_SYS(restart_syscall),
     94    SCMP_SYS(rt_sigaction),
     95    SCMP_SYS(rt_sigprocmask),
     96    SCMP_SYS(rt_sigreturn),
     97    SCMP_SYS(sched_getattr),
     98    SCMP_SYS(sched_setattr),
     99    SCMP_SYS(sendmsg),
    100    SCMP_SYS(setresgid),
    101    SCMP_SYS(setresuid),
    102#ifdef __NR_setresgid32
    103    SCMP_SYS(setresgid32),
    104#endif
    105#ifdef __NR_setresuid32
    106    SCMP_SYS(setresuid32),
    107#endif
    108    SCMP_SYS(set_robust_list),
    109    SCMP_SYS(setxattr),
    110    SCMP_SYS(symlinkat),
    111    SCMP_SYS(time), /* Rarely needed, except on static builds */
    112    SCMP_SYS(tgkill),
    113    SCMP_SYS(unlinkat),
    114    SCMP_SYS(unshare),
    115    SCMP_SYS(utimensat),
    116    SCMP_SYS(write),
    117    SCMP_SYS(writev),
    118    SCMP_SYS(umask),
    119};
    120
    121/* Syscalls used when --syslog is enabled */
    122static const int syscall_allowlist_syslog[] = {
    123    SCMP_SYS(send),
    124    SCMP_SYS(sendto),
    125};
    126
    127static void add_allowlist(scmp_filter_ctx ctx, const int syscalls[], size_t len)
    128{
    129    size_t i;
    130
    131    for (i = 0; i < len; i++) {
    132        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls[i], 0) != 0) {
    133            fuse_log(FUSE_LOG_ERR, "seccomp_rule_add syscall %d failed\n",
    134                     syscalls[i]);
    135            exit(1);
    136        }
    137    }
    138}
    139
    140void setup_seccomp(bool enable_syslog)
    141{
    142    scmp_filter_ctx ctx;
    143
    144#ifdef SCMP_ACT_KILL_PROCESS
    145    ctx = seccomp_init(SCMP_ACT_KILL_PROCESS);
    146    /* Handle a newer libseccomp but an older kernel */
    147    if (!ctx && errno == EOPNOTSUPP) {
    148        ctx = seccomp_init(SCMP_ACT_TRAP);
    149    }
    150#else
    151    ctx = seccomp_init(SCMP_ACT_TRAP);
    152#endif
    153    if (!ctx) {
    154        fuse_log(FUSE_LOG_ERR, "seccomp_init() failed\n");
    155        exit(1);
    156    }
    157
    158    add_allowlist(ctx, syscall_allowlist, G_N_ELEMENTS(syscall_allowlist));
    159    if (enable_syslog) {
    160        add_allowlist(ctx, syscall_allowlist_syslog,
    161                      G_N_ELEMENTS(syscall_allowlist_syslog));
    162    }
    163
    164    /* libvhost-user calls this for post-copy migration, we don't need it */
    165    if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS),
    166                         SCMP_SYS(userfaultfd), 0) != 0) {
    167        fuse_log(FUSE_LOG_ERR, "seccomp_rule_add userfaultfd failed\n");
    168        exit(1);
    169    }
    170
    171    if (seccomp_load(ctx) < 0) {
    172        fuse_log(FUSE_LOG_ERR, "seccomp_load() failed\n");
    173        exit(1);
    174    }
    175
    176    seccomp_release(ctx);
    177}