pull-seccomp-20190327

-----BEGIN PGP SIGNATURE-----
 
 iQEcBAABAgAGBQJcm2i3AAoJEN8y58Dw//mi/A0H/0uvALF0F7MMgmFgyZ1nT6FL
 OZAOJSDz+E+mC6soRdPzKmk/9v4aW0Z2azW6qaHVQtLkeLacs2CSV73NUXH7WmIG
 r7LhZeecMS8c3qk/oxfdNPvALOM+fM87jbm3IlPWUnYCqGXZW407aPM5k/yQaCxz
 J4bMsT6jCGq3KyXsnO5JqsWCWSkFVp+XSpJiT2kv2izdJcxP75JdYNTqUOhOTcDI
 uzdiFXJSUQuAPcVdNXgp02bmgj6N+lqpwfwsyHXwsxaDZ//sPscCHLy5nejYFHt7
 XWl47eAwsgAWT8L4A52494RYAUZ0hBHrcSLjq3lyydO81pKUaYktaAS3MOOdkDk=
 =EsXR
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/otubo/tags/pull-seccomp-20190327' into staging

pull-seccomp-20190327

# gpg: Signature made Wed 27 Mar 2019 12:12:39 GMT
# gpg:                using RSA key DF32E7C0F0FFF9A2
# gpg: Good signature from "Eduardo Otubo (Senior Software Engineer) <otubo@redhat.com>" [full]
# Primary key fingerprint: D67E 1B50 9374 86B4 0723  DBAB DF32 E7C0 F0FF F9A2

* remotes/otubo/tags/pull-seccomp-20190327:
  seccomp: report more useful errors from seccomp
  seccomp: don't kill process for resource control syscalls

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-03-28 12:04:52 +00:00
commit 12f067cc14

View File

@ -121,58 +121,84 @@ qemu_seccomp(unsigned int operation, unsigned int flags, void *args)
#endif #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) && \ #if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \
defined(SECCOMP_RET_KILL_PROCESS) defined(SECCOMP_RET_KILL_PROCESS)
{ static int kill_process = -1;
if (kill_process == -1) {
uint32_t action = SECCOMP_RET_KILL_PROCESS; 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; return SCMP_ACT_KILL_PROCESS;
} }
}
#endif #endif
return SCMP_ACT_TRAP; return SCMP_ACT_TRAP;
} }
case QEMU_SECCOMP_SET_RESOURCECTL:
return SCMP_ACT_ERRNO(EPERM);
static int seccomp_start(uint32_t seccomp_opts) default:
g_assert_not_reached();
}
}
static int seccomp_start(uint32_t seccomp_opts, Error **errp)
{ {
int rc = 0; int rc = -1;
unsigned int i = 0; unsigned int i = 0;
scmp_filter_ctx ctx; scmp_filter_ctx ctx;
uint32_t action = qemu_seccomp_get_kill_action();
ctx = seccomp_init(SCMP_ACT_ALLOW); ctx = seccomp_init(SCMP_ACT_ALLOW);
if (ctx == NULL) { if (ctx == NULL) {
rc = -1; error_setg(errp, "failed to initialize seccomp context");
goto seccomp_return; goto seccomp_return;
} }
rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1); rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1);
if (rc != 0) { if (rc != 0) {
error_setg_errno(errp, -rc,
"failed to set seccomp thread synchronization");
goto seccomp_return; goto seccomp_return;
} }
for (i = 0; i < ARRAY_SIZE(blacklist); i++) { for (i = 0; i < ARRAY_SIZE(blacklist); i++) {
uint32_t action;
if (!(seccomp_opts & blacklist[i].set)) { if (!(seccomp_opts & blacklist[i].set)) {
continue; continue;
} }
action = qemu_seccomp_get_action(blacklist[i].set);
rc = seccomp_rule_add_array(ctx, action, blacklist[i].num, rc = seccomp_rule_add_array(ctx, action, blacklist[i].num,
blacklist[i].narg, blacklist[i].arg_cmp); blacklist[i].narg, blacklist[i].arg_cmp);
if (rc < 0) { if (rc < 0) {
error_setg_errno(errp, -rc,
"failed to add seccomp blacklist rules");
goto seccomp_return; goto seccomp_return;
} }
} }
rc = seccomp_load(ctx); rc = seccomp_load(ctx);
if (rc < 0) {
error_setg_errno(errp, -rc,
"failed to load seccomp syscall filter in kernel");
}
seccomp_return: seccomp_return:
seccomp_release(ctx); seccomp_release(ctx);
return rc; return rc < 0 ? -1 : 0;
} }
#ifdef CONFIG_SECCOMP #ifdef CONFIG_SECCOMP
@ -242,9 +268,7 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp)
} }
} }
if (seccomp_start(seccomp_opts) < 0) { if (seccomp_start(seccomp_opts, errp) < 0) {
error_setg(errp, "failed to install seccomp syscall filter "
"in the kernel");
return -1; return -1;
} }
} }