From nobody Fri Oct 3 11:37:54 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1579809308; cv=none; d=zohomail.com; s=zohoarc; b=JdgrF+2FvWYwEl3BLg2VDLS17xGimGcWNslpUlcACKuku/1Wk8/h9OY0rbAS2uieIPDZgtlaJr6fD+qd5UItHdpqjlU/7Rs8HccuTDkyp2XkQMJLy8FxCJK/NNAqC0bMF3LCCveWVxxH3SEn1I0y5U0qBstGmupZyEz3ujEtC6Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579809308; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=KK/7qgjHzoRF+pgAqQJZ36ORUn7lwgLqQgxeveozNWk=; b=aORi1jj0Pm++APIOFZ6cuvhpcdt+pDbG90TCA5OKhyvE3tTiefmniZ3ZxqnXUJ/Q5EQlgalbx8tIwBhJRFmVwJx1tuA6619vW23bfxR7jwn9+exz3MTYXUfiJjhLCfcaovkpyhIjbkuIlOpay6Xtb0aqxOVQYEmpCWg6ucpQJaQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579809308169818.1670322548375; Thu, 23 Jan 2020 11:55:08 -0800 (PST) Received: from localhost ([::1]:60832 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iuiZE-0005IT-Vh for importer@patchew.org; Thu, 23 Jan 2020 14:55:05 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41409) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iufe5-00056f-LU for qemu-devel@nongnu.org; Thu, 23 Jan 2020 11:47:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iufe3-0006ch-W1 for qemu-devel@nongnu.org; Thu, 23 Jan 2020 11:47:53 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:35899 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iufe3-0006cW-TM for qemu-devel@nongnu.org; Thu, 23 Jan 2020 11:47:51 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-141-O8S-h3NCOt-Oe4t1-nrBfA-1; Thu, 23 Jan 2020 11:47:50 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 63A091085946 for ; Thu, 23 Jan 2020 16:47:49 +0000 (UTC) Received: from dgilbert-t580.localhost (ovpn-116-110.ams2.redhat.com [10.36.116.110]) by smtp.corp.redhat.com (Postfix) with ESMTP id B1B7728990; Thu, 23 Jan 2020 16:47:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1579798071; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KK/7qgjHzoRF+pgAqQJZ36ORUn7lwgLqQgxeveozNWk=; b=Daj47p4pQwIoi1JaIr8pmH5V3fKfDZ17rBc5dkmTUmdS4kDald8d1hfLgvwn9xxNIL0D5Z GZ+ZsNq+dheTefcaM7+975KqDtNkEJxVg0FO3u2nehsB1w77jK0LVdDA9kEDzT/q+V5Ul3 ec9fssGULGHrPOR17fwwhSA10seSDq4= From: "Dr. David Alan Gilbert (git)" To: qemu-devel@nongnu.org, stefanha@redhat.com Subject: [PULL 052/108] virtiofsd: add seccomp whitelist Date: Thu, 23 Jan 2020 16:45:34 +0000 Message-Id: <20200123164630.91498-53-dgilbert@redhat.com> In-Reply-To: <20200123164630.91498-1-dgilbert@redhat.com> References: <20200123164630.91498-1-dgilbert@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-MC-Unique: O8S-h3NCOt-Oe4t1-nrBfA-1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" From: Stefan Hajnoczi Only allow system calls that are needed by virtiofsd. All other system calls cause SIGSYS to be directed at the thread and the process will coredump. Restricting system calls reduces the kernel attack surface and limits what the process can do when compromised. Signed-off-by: Stefan Hajnoczi with additional entries by: Signed-off-by: Ganesh Maharaj Mahalingam Signed-off-by: Masayoshi Mizuma Signed-off-by: Misono Tomohiro Signed-off-by: piaojun Signed-off-by: Vivek Goyal Signed-off-by: Eric Ren Signed-off-by: Dr. David Alan Gilbert --- Makefile | 5 +- tools/virtiofsd/Makefile.objs | 5 +- tools/virtiofsd/passthrough_ll.c | 2 + tools/virtiofsd/seccomp.c | 151 +++++++++++++++++++++++++++++++ tools/virtiofsd/seccomp.h | 14 +++ 5 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 tools/virtiofsd/seccomp.c create mode 100644 tools/virtiofsd/seccomp.h diff --git a/Makefile b/Makefile index 2f81271ee7..ad400f36b2 100644 --- a/Makefile +++ b/Makefile @@ -327,7 +327,7 @@ HELPERS-y +=3D vhost-user-gpu$(EXESUF) vhost-user-json-y +=3D contrib/vhost-user-gpu/50-qemu-gpu.json endif =20 -ifdef CONFIG_LINUX +ifeq ($(CONFIG_LINUX)$(CONFIG_SECCOMP),yy) HELPERS-y +=3D virtiofsd$(EXESUF) vhost-user-json-y +=3D tools/virtiofsd/50-qemu-virtiofsd.json endif @@ -674,7 +674,8 @@ rdmacm-mux$(EXESUF): LIBS +=3D "-libumad" rdmacm-mux$(EXESUF): $(rdmacm-mux-obj-y) $(COMMON_LDADDS) $(call LINK, $^) =20 -ifdef CONFIG_LINUX # relies on Linux-specific syscalls +# relies on Linux-specific syscalls +ifeq ($(CONFIG_LINUX)$(CONFIG_SECCOMP),yy) virtiofsd$(EXESUF): $(virtiofsd-obj-y) libvhost-user.a $(COMMON_LDADDS) $(call LINK, $^) endif diff --git a/tools/virtiofsd/Makefile.objs b/tools/virtiofsd/Makefile.objs index 45a807500d..076f667e46 100644 --- a/tools/virtiofsd/Makefile.objs +++ b/tools/virtiofsd/Makefile.objs @@ -5,5 +5,8 @@ virtiofsd-obj-y =3D buffer.o \ fuse_signals.o \ fuse_virtio.o \ helper.o \ - passthrough_ll.o + passthrough_ll.o \ + seccomp.o =20 +seccomp.o-cflags :=3D $(SECCOMP_CFLAGS) +seccomp.o-libs :=3D $(SECCOMP_LIBS) diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough= _ll.c index 0947d14e5b..bd8925bd83 100644 --- a/tools/virtiofsd/passthrough_ll.c +++ b/tools/virtiofsd/passthrough_ll.c @@ -59,6 +59,7 @@ #include =20 #include "passthrough_helpers.h" +#include "seccomp.h" =20 struct lo_map_elem { union { @@ -2091,6 +2092,7 @@ static void setup_sandbox(struct lo_data *lo, struct = fuse_session *se) { setup_namespaces(lo, se); setup_mounts(lo->source); + setup_seccomp(); } =20 int main(int argc, char *argv[]) diff --git a/tools/virtiofsd/seccomp.c b/tools/virtiofsd/seccomp.c new file mode 100644 index 0000000000..691fb63dea --- /dev/null +++ b/tools/virtiofsd/seccomp.c @@ -0,0 +1,151 @@ +/* + * Seccomp sandboxing for virtiofsd + * + * Copyright (C) 2019 Red Hat, Inc. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "seccomp.h" +#include "fuse_i.h" +#include "fuse_log.h" +#include +#include +#include +#include + +/* Bodge for libseccomp 2.4.2 which broke ppoll */ +#if !defined(__SNR_ppoll) && defined(__SNR_brk) +#ifdef __NR_ppoll +#define __SNR_ppoll __NR_ppoll +#else +#define __SNR_ppoll __PNR_ppoll +#endif +#endif + +static const int syscall_whitelist[] =3D { + /* TODO ireg sem*() syscalls */ + SCMP_SYS(brk), + SCMP_SYS(capget), /* For CAP_FSETID */ + SCMP_SYS(capset), + SCMP_SYS(clock_gettime), + SCMP_SYS(clone), +#ifdef __NR_clone3 + SCMP_SYS(clone3), +#endif + SCMP_SYS(close), + SCMP_SYS(copy_file_range), + SCMP_SYS(dup), + SCMP_SYS(eventfd2), + SCMP_SYS(exit), + SCMP_SYS(exit_group), + SCMP_SYS(fallocate), + SCMP_SYS(fchmodat), + SCMP_SYS(fchownat), + SCMP_SYS(fcntl), + SCMP_SYS(fdatasync), + SCMP_SYS(fgetxattr), + SCMP_SYS(flistxattr), + SCMP_SYS(flock), + SCMP_SYS(fremovexattr), + SCMP_SYS(fsetxattr), + SCMP_SYS(fstat), + SCMP_SYS(fstatfs), + SCMP_SYS(fsync), + SCMP_SYS(ftruncate), + SCMP_SYS(futex), + SCMP_SYS(getdents), + SCMP_SYS(getdents64), + SCMP_SYS(getegid), + SCMP_SYS(geteuid), + SCMP_SYS(getpid), + SCMP_SYS(gettid), + SCMP_SYS(gettimeofday), + SCMP_SYS(linkat), + SCMP_SYS(lseek), + SCMP_SYS(madvise), + SCMP_SYS(mkdirat), + SCMP_SYS(mknodat), + SCMP_SYS(mmap), + SCMP_SYS(mprotect), + SCMP_SYS(mremap), + SCMP_SYS(munmap), + SCMP_SYS(newfstatat), + SCMP_SYS(open), + SCMP_SYS(openat), + SCMP_SYS(ppoll), + SCMP_SYS(prctl), /* TODO restrict to just PR_SET_NAME? */ + SCMP_SYS(preadv), + SCMP_SYS(pread64), + SCMP_SYS(pwritev), + SCMP_SYS(pwrite64), + SCMP_SYS(read), + SCMP_SYS(readlinkat), + SCMP_SYS(recvmsg), + SCMP_SYS(renameat), + SCMP_SYS(renameat2), + SCMP_SYS(rt_sigaction), + SCMP_SYS(rt_sigprocmask), + SCMP_SYS(rt_sigreturn), + SCMP_SYS(sendmsg), + SCMP_SYS(setresgid), + SCMP_SYS(setresuid), +#ifdef __NR_setresgid32 + SCMP_SYS(setresgid32), +#endif +#ifdef __NR_setresuid32 + SCMP_SYS(setresuid32), +#endif + SCMP_SYS(set_robust_list), + SCMP_SYS(symlinkat), + SCMP_SYS(time), /* Rarely needed, except on static builds */ + SCMP_SYS(tgkill), + SCMP_SYS(unlinkat), + SCMP_SYS(utimensat), + SCMP_SYS(write), + SCMP_SYS(writev), +}; + +void setup_seccomp(void) +{ + scmp_filter_ctx ctx; + size_t i; + +#ifdef SCMP_ACT_KILL_PROCESS + ctx =3D seccomp_init(SCMP_ACT_KILL_PROCESS); + /* Handle a newer libseccomp but an older kernel */ + if (!ctx && errno =3D=3D EOPNOTSUPP) { + ctx =3D seccomp_init(SCMP_ACT_TRAP); + } +#else + ctx =3D seccomp_init(SCMP_ACT_TRAP); +#endif + if (!ctx) { + fuse_log(FUSE_LOG_ERR, "seccomp_init() failed\n"); + exit(1); + } + + for (i =3D 0; i < G_N_ELEMENTS(syscall_whitelist); i++) { + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, + syscall_whitelist[i], 0) !=3D 0) { + fuse_log(FUSE_LOG_ERR, "seccomp_rule_add syscall %d", + syscall_whitelist[i]); + exit(1); + } + } + + /* libvhost-user calls this for post-copy migration, we don't need it = */ + if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), + SCMP_SYS(userfaultfd), 0) !=3D 0) { + fuse_log(FUSE_LOG_ERR, "seccomp_rule_add userfaultfd failed\n"); + exit(1); + } + + if (seccomp_load(ctx) < 0) { + fuse_log(FUSE_LOG_ERR, "seccomp_load() failed\n"); + exit(1); + } + + seccomp_release(ctx); +} diff --git a/tools/virtiofsd/seccomp.h b/tools/virtiofsd/seccomp.h new file mode 100644 index 0000000000..86bce72652 --- /dev/null +++ b/tools/virtiofsd/seccomp.h @@ -0,0 +1,14 @@ +/* + * Seccomp sandboxing for virtiofsd + * + * Copyright (C) 2019 Red Hat, Inc. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef VIRTIOFSD_SECCOMP_H +#define VIRTIOFSD_SECCOMP_H + +void setup_seccomp(void); + +#endif /* VIRTIOFSD_SECCOMP_H */ --=20 2.24.1