X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=qemu-seccomp.c;h=e0a1829b3ddc9732f357179b9c23ce4b48703efb;hb=550a04893c2bd4442211b353680b9a6408d94dba;hp=36d5829831760639a004e1a136d5d5e084ac4525;hpb=9f33051abce238ab43a23125e237aac8b0931b88;p=thirdparty%2Fqemu.git diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 36d58298317..e0a1829b3dd 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -121,58 +121,84 @@ qemu_seccomp(unsigned int operation, unsigned int flags, void *args) #endif } -static uint32_t qemu_seccomp_get_kill_action(void) +static uint32_t qemu_seccomp_get_action(int set) { + switch (set) { + case QEMU_SECCOMP_SET_DEFAULT: + case QEMU_SECCOMP_SET_OBSOLETE: + case QEMU_SECCOMP_SET_PRIVILEGED: + case QEMU_SECCOMP_SET_SPAWN: { #if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \ defined(SECCOMP_RET_KILL_PROCESS) - { - uint32_t action = SECCOMP_RET_KILL_PROCESS; + static int kill_process = -1; + if (kill_process == -1) { + uint32_t action = SECCOMP_RET_KILL_PROCESS; - if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) { + if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) { + kill_process = 1; + } + kill_process = 0; + } + if (kill_process == 1) { return SCMP_ACT_KILL_PROCESS; } - } #endif + return SCMP_ACT_TRAP; + } - return SCMP_ACT_TRAP; + case QEMU_SECCOMP_SET_RESOURCECTL: + return SCMP_ACT_ERRNO(EPERM); + + default: + g_assert_not_reached(); + } } -static int seccomp_start(uint32_t seccomp_opts) +static int seccomp_start(uint32_t seccomp_opts, Error **errp) { - int rc = 0; + int rc = -1; unsigned int i = 0; scmp_filter_ctx ctx; - uint32_t action = qemu_seccomp_get_kill_action(); ctx = seccomp_init(SCMP_ACT_ALLOW); if (ctx == NULL) { - rc = -1; + error_setg(errp, "failed to initialize seccomp context"); goto seccomp_return; } rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1); if (rc != 0) { + error_setg_errno(errp, -rc, + "failed to set seccomp thread synchronization"); goto seccomp_return; } for (i = 0; i < ARRAY_SIZE(blacklist); i++) { + uint32_t action; if (!(seccomp_opts & blacklist[i].set)) { continue; } + action = qemu_seccomp_get_action(blacklist[i].set); rc = seccomp_rule_add_array(ctx, action, blacklist[i].num, blacklist[i].narg, blacklist[i].arg_cmp); if (rc < 0) { + error_setg_errno(errp, -rc, + "failed to add seccomp blacklist rules"); goto seccomp_return; } } rc = seccomp_load(ctx); + if (rc < 0) { + error_setg_errno(errp, -rc, + "failed to load seccomp syscall filter in kernel"); + } seccomp_return: seccomp_release(ctx); - return rc; + return rc < 0 ? -1 : 0; } #ifdef CONFIG_SECCOMP @@ -242,9 +268,7 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } - if (seccomp_start(seccomp_opts) < 0) { - error_setg(errp, "failed to install seccomp syscall filter " - "in the kernel"); + if (seccomp_start(seccomp_opts, errp) < 0) { return -1; } }