From nobody Fri Mar 29 00:25:31 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1631143256; cv=none; d=zohomail.com; s=zohoarc; b=a59reUyCmll6X0t24LqmaILwF4x0nGMVsD/SLvaUYSlHzyt/z/w3OIJXjLGs1eoLj7eD/wAhuz3G6/YVnHQjQOiU9eO9pCDSE1wtNbf73PMWfMgi96UggQAtzW5w002kdHETs8j0Hq767csgJaBJd37D4bqqHvZW4mO0wm9Q4kQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1631143256; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=24r6QApw3vBXmuZyf+4hmvAM+x9sjvcUeNKNebXV07M=; b=EpRjDcSeEWk/b+nE0mZAyZoRcRJN1zesS+zEJZM++b9uAfsUzAc5TfaMTeeAdlMS1QBVsiSBU3qvkjkHdwyaQF1ah5UJ7oSVq6zOHXkPyJOgxJtzC9m50U8/av6cowhOu5Wp47DwwmSkCiNz7y22el0JF9paqaSHh+q+6VSYWig= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1631143256404865.5807447188363; Wed, 8 Sep 2021 16:20:56 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.182405.329943 (Exim 4.92) (envelope-from ) id 1mO6ru-0005Hm-Ex; Wed, 08 Sep 2021 23:20:38 +0000 Received: by outflank-mailman (output) from mailman id 182405.329943; Wed, 08 Sep 2021 23:20:38 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1mO6ru-0005Hd-BZ; Wed, 08 Sep 2021 23:20:38 +0000 Received: by outflank-mailman (input) for mailman id 182405; Wed, 08 Sep 2021 23:20:37 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1mO6rt-0005H5-57 for xen-devel@lists.xenproject.org; Wed, 08 Sep 2021 23:20:37 +0000 Received: from us-smtp-delivery-124.mimecast.com (unknown [170.10.133.124]) by us1-rack-iad1.inumbo.com (Halon) with ESMTP id 29ae4109-0146-4d0d-9aab-02903dff8a94; Wed, 08 Sep 2021 23:20:36 +0000 (UTC) Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-188-xr-uShr_OCCOqUsQg9aBEA-1; Wed, 08 Sep 2021 19:20:32 -0400 Received: by mail-wm1-f72.google.com with SMTP id h1-20020a05600c350100b002e751bf6733so27556wmq.8 for ; Wed, 08 Sep 2021 16:20:32 -0700 (PDT) Received: from x1w.. (21.red-83-52-55.dynamicip.rima-tde.net. [83.52.55.21]) by smtp.gmail.com with ESMTPSA id d24sm351621wmb.35.2021.09.08.16.20.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Sep 2021 16:20:30 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 29ae4109-0146-4d0d-9aab-02903dff8a94 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1631143235; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=24r6QApw3vBXmuZyf+4hmvAM+x9sjvcUeNKNebXV07M=; b=cHMSEsH74t2LvVloVlfq4EvD+YK4jqLIsSY4YFJusw8TgkB2ciE6ChM/g1pmYKdE0f9ZOJ XPBjIoKkp3S6WWLeZg8vBtc3kD6MGqMCDuJziJOhsqagrbrF1YyCwNW8JW8rlivQ5In0B6 LSsJq/esbeEV0randd9PzKnI4N0eeac= X-MC-Unique: xr-uShr_OCCOqUsQg9aBEA-1 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=24r6QApw3vBXmuZyf+4hmvAM+x9sjvcUeNKNebXV07M=; b=OSEQ+1btCzwIP0Fjw06aUhpWT7CZ/JirzP7Qh7uRHA81iDx+/TKmGKriDqYzsIU3Qt 0QpPU6aL5Ceb0AFD2H7U3GG315dR29AZjzFvZlDb4G4wweNG95prTSd5nqwMFHCvpGdX OEceVtNGpKlh8VUdH8y0Ul1xHwmkQi1TxaMhGf03/a9BMS2WvpjTeHwjjUsS9Ao3AnTO DPCyQSdViIRS78NO+mbdtYjKdfsrGr0jplBiABg3nBLWH//w5p1kt4G6bZJkatONQYD4 dzFNmseoLFC4tclXtDcDK8CQHWcoTcNve/6hEIoGziRoazq+S5imVpqZpJpz3lHJExxm USXw== X-Gm-Message-State: AOAM533OX6TrTHtxLJU8dl6515fkYRDl0SSQ795hNvUAN8nD0pdiiKMJ RMOcjOb3p5nCgmS4XFuVYV46vOwhvCRkXsuaszn9eruDL9V8+hUObr4uuQ6kZvA74jskDRQqDTI G+aAlbPxWLMtK66MxyDzQmfsWQtM= X-Received: by 2002:a1c:a505:: with SMTP id o5mr581205wme.32.1631143231080; Wed, 08 Sep 2021 16:20:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxASJCusoNVcbOBdnL042tIJLhajKX+g6Wmf6M6mn99T6nfkEBgAxNrSyEjSzJ0g2TtZ/mq2Q== X-Received: by 2002:a1c:a505:: with SMTP id o5mr581183wme.32.1631143230848; Wed, 08 Sep 2021 16:20:30 -0700 (PDT) From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Thomas Huth , Prasad J Pandit , "Michael S. Tsirkin" , Markus Armbruster , Paolo Bonzini , Eduardo Habkost , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Eric Blake , Richard Henderson , qemu-block@nongnu.org, Peter Maydell , xen-devel@lists.xenproject.org, =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [RFC PATCH 01/10] sysemu: Introduce qemu_security_policy_taint() API Date: Thu, 9 Sep 2021 01:20:15 +0200 Message-Id: <20210908232024.2399215-2-philmd@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210908232024.2399215-1-philmd@redhat.com> References: <20210908232024.2399215-1-philmd@redhat.com> MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=philmd@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1631143256944100007 Introduce qemu_security_policy_taint() which allows unsafe (read "not very maintained") code to 'taint' QEMU security policy. The "security policy" is the @SecurityPolicy QAPI enum, composed of: - "none" (no policy, current behavior) - "warn" (display a warning when the policy is tainted, keep going) - "strict" (once tainted, exit QEMU before starting the VM) The qemu_security_policy_is_strict() helper is also provided, which will be proved useful once a VM is started (example we do not want to kill a running VM if an unsafe device is hot-added). Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- qapi/run-state.json | 16 +++++++++++ include/qemu-common.h | 19 ++++++++++++ softmmu/vl.c | 67 +++++++++++++++++++++++++++++++++++++++++++ qemu-options.hx | 17 +++++++++++ 4 files changed, 119 insertions(+) diff --git a/qapi/run-state.json b/qapi/run-state.json index 43d66d700fc..b15a107fa01 100644 --- a/qapi/run-state.json +++ b/qapi/run-state.json @@ -638,3 +638,19 @@ { 'struct': 'MemoryFailureFlags', 'data': { 'action-required': 'bool', 'recursive': 'bool'} } + +## +# @SecurityPolicy: +# +# An enumeration of the actions taken when the security policy is tainted. +# +# @none: do nothing. +# +# @warn: display a warning. +# +# @strict: prohibit QEMU to start a VM. +# +# Since: 6.2 +## +{ 'enum': 'SecurityPolicy', + 'data': [ 'none', 'warn', 'strict' ] } diff --git a/include/qemu-common.h b/include/qemu-common.h index 73bcf763ed8..bf0b054bb66 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -139,4 +139,23 @@ void page_size_init(void); * returned. */ bool dump_in_progress(void); =20 +/** + * qemu_security_policy_taint: + * @tainting whether any security policy is tainted (compromised). + * @fmt: taint reason format string + * ...: list of arguments to interpolate into @fmt, like printf(). + * + * Allow unsafe code path to taint the global security policy. + * See #SecurityPolicy. + */ +void qemu_security_policy_taint(bool tainting, const char *fmt, ...) + GCC_FMT_ATTR(2, 3); + +/** + * qemu_security_policy_is_strict: + * + * Return %true if the global security policy is 'strict', %false otherwis= e. + */ +bool qemu_security_policy_is_strict(void); + #endif diff --git a/softmmu/vl.c b/softmmu/vl.c index 55ab70eb97f..92c05ac97ee 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -489,6 +489,20 @@ static QemuOptsList qemu_action_opts =3D { }, }; =20 +static QemuOptsList qemu_security_policy_opts =3D { + .name =3D "security-policy", + .implied_opt_name =3D "policy", + .merge_lists =3D true, + .head =3D QTAILQ_HEAD_INITIALIZER(qemu_security_policy_opts.head), + .desc =3D { + { + .name =3D "policy", + .type =3D QEMU_OPT_STRING, + }, + { /* end of list */ } + }, +}; + const char *qemu_get_vm_name(void) { return qemu_name; @@ -600,6 +614,52 @@ static int cleanup_add_fd(void *opaque, QemuOpts *opts= , Error **errp) } #endif =20 +static SecurityPolicy security_policy =3D SECURITY_POLICY_NONE; + +bool qemu_security_policy_is_strict(void) +{ + return security_policy =3D=3D SECURITY_POLICY_STRICT; +} + +static int select_security_policy(const char *p) +{ + int policy; + char *qapi_value; + + qapi_value =3D g_ascii_strdown(p, -1); + policy =3D qapi_enum_parse(&SecurityPolicy_lookup, qapi_value, -1, NUL= L); + g_free(qapi_value); + if (policy < 0) { + return -1; + } + security_policy =3D policy; + + return 0; +} + +void qemu_security_policy_taint(bool tainting, const char *fmt, ...) +{ + va_list ap; + g_autofree char *efmt =3D NULL; + + if (security_policy =3D=3D SECURITY_POLICY_NONE || !tainting) { + return; + } + + va_start(ap, fmt); + if (security_policy =3D=3D SECURITY_POLICY_STRICT) { + efmt =3D g_strdup_printf("%s taints QEMU security policy, exiting.= ", fmt); + error_vreport(efmt, ap); + exit(EXIT_FAILURE); + } else if (security_policy =3D=3D SECURITY_POLICY_WARN) { + efmt =3D g_strdup_printf("%s taints QEMU security policy.", fmt); + warn_vreport(efmt, ap); + } else { + g_assert_not_reached(); + } + va_end(ap); +} + /***********************************************************/ /* QEMU Block devices */ =20 @@ -2764,6 +2824,7 @@ void qemu_init(int argc, char **argv, char **envp) qemu_add_opts(&qemu_semihosting_config_opts); qemu_add_opts(&qemu_fw_cfg_opts); qemu_add_opts(&qemu_action_opts); + qemu_add_opts(&qemu_security_policy_opts); module_call_init(MODULE_INIT_OPTS); =20 error_init(argv[0]); @@ -3230,6 +3291,12 @@ void qemu_init(int argc, char **argv, char **envp) exit(1); } break; + case QEMU_OPTION_security_policy: + if (select_security_policy(optarg) =3D=3D -1) { + error_report("unknown -security-policy parameter"); + exit(1); + } + break; case QEMU_OPTION_parallel: add_device_config(DEV_PARALLEL, optarg); default_parallel =3D 0; diff --git a/qemu-options.hx b/qemu-options.hx index 8f603cc7e65..d9939f7ae1d 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4298,6 +4298,23 @@ SRST =20 ERST =20 +DEF("security-policy", HAS_ARG, QEMU_OPTION_security_policy, \ + "-security-policy none|warn|strict\n" \ + " action when security policy is tainted [default=3Dno= ne]\n", + QEMU_ARCH_ALL) +SRST +``-security-policy policy`` + The policy controls what QEMU will do when an unsecure feature is + used, tainting the process security. The default is ``none`` (do + nothing). Other possible actions are: ``warn`` (display a warning + and keep going) or ``strict`` (exits QEMU before launching a VM). + + Examples: + + ``-security-policy warn``; \ ``-security-policy strict`` + +ERST + DEF("echr", HAS_ARG, QEMU_OPTION_echr, \ "-echr chr set terminal escape character instead of ctrl-a\n", QEMU_ARCH_ALL) --=20 2.31.1