From nobody Mon Apr 29 05:16:39 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=quarantine dis=quarantine) header.from=suse.com Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1629327556798374.9895378359355; Wed, 18 Aug 2021 15:59:16 -0700 (PDT) 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-318-0VVdMQjvMcmlie_pISCRag-1; Wed, 18 Aug 2021 18:59:14 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 480448042EF; Wed, 18 Aug 2021 22:59:08 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2911760938; Wed, 18 Aug 2021 22:59:06 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id A10224BB7C; Wed, 18 Aug 2021 22:59:01 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 17IMvexg026066 for ; Wed, 18 Aug 2021 18:57:40 -0400 Received: by smtp.corp.redhat.com (Postfix) id 47C9AF3D16; Wed, 18 Aug 2021 22:57:40 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast05.extmail.prod.ext.rdu2.redhat.com [10.11.55.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 40D2EEE84E for ; Wed, 18 Aug 2021 22:57:37 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E9FC9803DD7 for ; Wed, 18 Aug 2021 22:57:36 +0000 (UTC) Received: from de-smtp-delivery-102.mimecast.com (de-smtp-delivery-102.mimecast.com [194.104.111.102]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-179-rsZrDXiUPkS7CLr8C0kuJw-1; Wed, 18 Aug 2021 18:57:34 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-he1eur04lp2059.outbound.protection.outlook.com [104.47.13.59]) (Using TLS) by relay.mimecast.com with ESMTP id de-mta-12-AF1kgxLeMRWPJ4mEYIoOGQ-1; Thu, 19 Aug 2021 00:57:32 +0200 Received: from AM8PR04MB7970.eurprd04.prod.outlook.com (2603:10a6:20b:24f::9) by AM0PR04MB6210.eurprd04.prod.outlook.com (2603:10a6:208:13b::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4415.17; Wed, 18 Aug 2021 22:57:30 +0000 Received: from AM8PR04MB7970.eurprd04.prod.outlook.com ([fe80::5d01:f91d:8ffa:b5c3]) by AM8PR04MB7970.eurprd04.prod.outlook.com ([fe80::5d01:f91d:8ffa:b5c3%6]) with mapi id 15.20.4415.024; Wed, 18 Aug 2021 22:57:30 +0000 Received: from localhost (69.51.74.89) by PR3PR09CA0006.eurprd09.prod.outlook.com (2603:10a6:102:b7::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4436.19 via Frontend Transport; Wed, 18 Aug 2021 22:57:29 +0000 X-MC-Unique: 0VVdMQjvMcmlie_pISCRag-1 X-MC-Unique: rsZrDXiUPkS7CLr8C0kuJw-1 X-MC-Unique: AF1kgxLeMRWPJ4mEYIoOGQ-1 From: Jim Fehlig To: libvir-list@redhat.com Subject: [PATCH V2] qemu: Set label on vhostuser net device when hotplugging Date: Wed, 18 Aug 2021 16:57:26 -0600 Message-ID: <20210818225726.29229-1-jfehlig@suse.com> X-ClientProxiedBy: PR3PR09CA0006.eurprd09.prod.outlook.com (2603:10a6:102:b7::11) To AM8PR04MB7970.eurprd04.prod.outlook.com (2603:10a6:20b:24f::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: c50459d3-7ec4-4968-6761-08d9629b8ea3 X-MS-TrafficTypeDiagnostic: AM0PR04MB6210: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:4941 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0 X-Microsoft-Antispam-Message-Info: mJSqx0j/GhpriBaBfBgstaAHSjf3H5I9FknRkJP0/xVz31Vu1RR0t1RR9Gg2F5sCkSNrSd0QXUVCNLzf2cdTRazS0UTg6cXJ+PlBkxzVwSjHiTbHJoC3SzF8TVB8lQzbZIQzB4U+efRomfHTSPLwybVo+dxosDT88uYSY6faIFxNVEYPH9LQEoquIetKccceGZ2aiQciC8yominYhHLTdggvOTUM2k9V3qBpDO5xvpN5m4bTeldu6UvHux7p7ZgekjL1zZjf9kxxqA1DPLExm7gG3JJNPobTztexCVsiJPYH0G7E+MIu0Zu590C4MXM+jXyElHNYsM4gq2uLDBeJaSLjSQOrmUv+rFuKNwBG1P6H3upjfeJfV78XdG04MnJlwQq8X4/mpGqF3BGSxrtQhfrGDBkc1Fr03qqs7kuk/WRQjqCSCvqD+1bBsW5J9UoxCv2kr+cytzdtYd4tetSu+RfyAePejIsGt1R9nir79UJCalGgwNvJ2YEZVisyZUoPFsvgHGWOiBgntPiM+3NYE9pwW+CPDNSVbjYvn2lDj6TTNFVk/QzA0ImeVs1NVQ0QIRqzCW+teUamBdqhcg4Ol+LWW1MXQrnmGbpoGvVS5g3nf/R5ceQOuQhUKNi0lkn2XY7ym1kPAWpagXhB7p8oX+FUnnhILl1d2URMOcvx+7R9CC6BXL5iJkWVfHvW21JwRVkSBw8GBRPAaRGLrun/G1uR/pxbp7PdBUI7MHlWM5uo91apZgqO6hwI/rTE15Fj+INeSuSwpyMxQgH14KFH4Q== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM8PR04MB7970.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(376002)(136003)(346002)(396003)(39850400004)(5660300002)(26005)(6666004)(956004)(2616005)(6486002)(186003)(316002)(66556008)(66476007)(66946007)(8936002)(8676002)(478600001)(6496006)(86362001)(966005)(2906002)(1076003)(6916009)(83380400001)(36756003)(38100700002)(30864003)(44824005); DIR:OUT; SFP:1101 X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?gTnPazbghdBmOMYK61UbefdMYeWmcts0hC8UGfxCocMIj3xhMul6vJ6+zC4u?= =?us-ascii?Q?LAmZKIpUbZPpenczyL2KNd5+wkxjiMzu7KysQZ6oi1BIDHdq18Vt2k046MNb?= =?us-ascii?Q?iYroWRDwa64Wq+ehUtoZzKma1+hrzYa/5PjLf0yR5VYr6yWEtyKJT5ayxz44?= =?us-ascii?Q?jUNsYBGUklGS+zScCNDMFdRlQ92RFDanN/5QfeM1eNJ5aQ1U6OAHkpOe2oV+?= =?us-ascii?Q?0z3fhfrKnTyM7FseoJV6Pa0Ha7RuRl0HgkoUcPbicsKIId4p64nip6xyS1vX?= =?us-ascii?Q?QfRpbhDLYrFzK3JBF5/OE62IiUSAnTvTrfSWr0nz9zncRWE0PArnVEiS1Xh1?= =?us-ascii?Q?zbsiVGZjYRODRvsVsiGXPXIo37A/W8U58+pu5CMMKCs4ZTIoilzh2voHLnvK?= =?us-ascii?Q?ubg1zXPZRilVnQYMFrCxvT4BUh1HG5iSEzxJtJpXDgWQohWsumDcZKo/usBY?= =?us-ascii?Q?ZRQeK73a1FjB3ehkGcdrAFqlH/2JHhD3RcC5O4+WublIwsF2J9cvLGn9GXHx?= =?us-ascii?Q?LpZYraiszysf5SoDI6TheBTElPrQ880COrvpqxEv6Y7KVB2MKsXKmDA3QeHu?= =?us-ascii?Q?CXilhvwtBC2tzQeIwxcW+/d2hxu7wYTQ8VYAooGZdqAX0nmwW2v3DTXwt0zG?= =?us-ascii?Q?z6p4uPD+jdTXbn88bbBgiNHDIu+mD0AXF6ZgyZFoUom5fUyJZ8f96WOBqAul?= =?us-ascii?Q?UALVIAg5kIX1sPvZwJpKvZnVglnp9J2aglVGp9JfV/ixVt9i7PUHY+CWpnoe?= =?us-ascii?Q?gnmeIg2wyxu8mHbglWEg5Fkc8AM5FhKEhCjaMbqpV6/e2QYexzPQz+TjZbnG?= =?us-ascii?Q?ZRXzb6fNEYedKosbFIhRSeiM3eqq0/L/j1W17gmPOGTDtgHt4BreOh741v7A?= =?us-ascii?Q?dR2p8sxB3DyfTu2hxkgn0N7wPzrUX/SPgvcK/y/sYzHWx5Yd816q4jKFh0YX?= =?us-ascii?Q?FX6BmAbmF67MQkJiz5IvpaFXhG1DoJ8kMk+uceZk562epcmmP0c6mM4pOwgS?= =?us-ascii?Q?riwB1P/u5bUiXJiW5O6TWY4WcJXuIeAXBq3ENmwmbrr613QPS6C84rCB+twR?= =?us-ascii?Q?ROzd4i66q72K5+JIaEgFEWUkrUuwNjjSa2Chtn8a49VTkR88sC2HRRY+xXx0?= =?us-ascii?Q?+P3/qr9MGOFtM1EI5FT+64NIYhcVikvUHN7U0YqqWixU4+Gldo8GqTaC+j5t?= =?us-ascii?Q?E91LVZwxSG409tqLA2fgwo5HWAi1YZQRHCyqhaXOJ8D2OfMumrY33B+dlS1V?= =?us-ascii?Q?rr89jCV1Rm4gEjty1awkoUIAmj/vECBgaJpciNfq4/Ad735Zg6760CvHqgJv?= =?us-ascii?Q?fckYAAiu8bbHX1SkBIStPyN8?= X-OriginatorOrg: suse.com X-MS-Exchange-CrossTenant-Network-Message-Id: c50459d3-7ec4-4968-6761-08d9629b8ea3 X-MS-Exchange-CrossTenant-AuthSource: AM8PR04MB7970.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Aug 2021 22:57:30.5517 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f7a17af6-1c5c-4a36-aa8b-f5be247aa4ba X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: cMj4UW0JausHdPWgiZZv7BTWqSuk4cEx9NUggO8OOi2skkeHJlUgcCCyBbg88qFmtmKAOLS+uM5G5XL8rTI3SA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR04MB6210 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-MIME-Autoconverted: from quoted-printable to 8bit by lists01.pubmisc.prod.ext.phx2.redhat.com id 17IMvexg026066 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1629327558622100001 Content-Type: text/plain; charset="utf-8" Attaching a newly created vhostuser port to a VM fails due to an apparmor denial internal error: unable to execute QEMU command 'chardev-add': Failed to bind socket to /run/openvswitch/vhu838c4d29-c9: Permission denied In the case of a net device type VIR_DOMAIN_NET_TYPE_VHOSTUSER, the underlying chardev is not labeled in qemuDomainAttachNetDevice prior to calling qemuMonitorAttachCharDev. A simple fix would be to call qemuSecuritySetChardevLabel using the embedded virDomainChrSourceDef in the virDomainNetDef vhostuser data, but this incurs the risk of incorrectly restoring the label. E.g. consider the DAC driver behavior with a vhostuser net device, which uses a socket for the chardev backend. The DAC driver uses XATTRS to store original labelling information, but XATTRS are not compatible with sockets. Without the original labelling information, the socket labels will be restored with root ownership, preventing other less-privileged processes from connecting to the socket. This patch avoids overloading chardev labelling with vhostuser net devices by introducing virSecurityManager{Set,Restore}NetdevLabel, which is currently only implemented for the apparmor driver. The new APIs are then used to set and restore labels for the vhostuser net devices. Signed-off-by: Jim Fehlig Reviewed-by: Michal Privoznik --- V2 of: https://listman.redhat.com/archives/libvir-list/2021-August/msg00373.html Changes since V1: Introduce and use new APIs for labeling net devices Don't perform labelling while executing monitor commands Restore labels if hotplug fails src/libvirt_private.syms | 2 ++ src/qemu/qemu_hotplug.c | 13 +++++++ src/qemu/qemu_security.c | 59 ++++++++++++++++++++++++++++++ src/qemu/qemu_security.h | 8 +++++ src/security/security_apparmor.c | 61 ++++++++++++++++++++++++++++++++ src/security/security_driver.h | 9 +++++ src/security/security_manager.c | 38 ++++++++++++++++++++ src/security/security_manager.h | 8 +++++ src/security/security_stack.c | 52 +++++++++++++++++++++++++++ 9 files changed, 250 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fcb02c21b1..9d3e0421c0 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1687,6 +1687,7 @@ virSecurityManagerRestoreHostdevLabel; virSecurityManagerRestoreImageLabel; virSecurityManagerRestoreInputLabel; virSecurityManagerRestoreMemoryLabel; +virSecurityManagerRestoreNetdevLabel; virSecurityManagerRestoreSavedStateLabel; virSecurityManagerRestoreTPMLabels; virSecurityManagerSetAllLabel; @@ -1698,6 +1699,7 @@ virSecurityManagerSetImageFDLabel; virSecurityManagerSetImageLabel; virSecurityManagerSetInputLabel; virSecurityManagerSetMemoryLabel; +virSecurityManagerSetNetdevLabel; virSecurityManagerSetProcessLabel; virSecurityManagerSetSavedStateLabel; virSecurityManagerSetSocketLabel; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index c3c49fe080..77dbf69845 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1203,6 +1203,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, g_autofree char *netdev_name =3D NULL; g_autoptr(virConnect) conn =3D NULL; virErrorPtr save_err =3D NULL; + bool teardownlabel =3D false; =20 /* If appropriate, grab a physical device from the configured * network's pool of devices, or resolve bridge device name @@ -1343,6 +1344,9 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, &net->ifname) < 0) goto cleanup; =20 + if (qemuSecuritySetNetdevLabel(driver, vm, net) < 0) + goto cleanup; + teardownlabel =3D true; break; =20 case VIR_DOMAIN_NET_TYPE_USER: @@ -1559,6 +1563,10 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, qemuDomainNetDeviceVportRemove(net); } =20 + if (teardownlabel && + qemuSecurityRestoreNetdevLabel(driver, vm, net) < 0) + VIR_WARN("Unable to restore network device labelling on hotplu= g fail"); + /* we had potentially pre-added the device to the domain * device lists, if so we need to remove it (from def->nets * and/or def->hostdevs) on failure @@ -4763,6 +4771,11 @@ qemuDomainRemoveNetDevice(virQEMUDriver *driver, cfg->stateDir)); } =20 + if (actualType =3D=3D VIR_DOMAIN_NET_TYPE_VHOSTUSER) { + if (qemuSecurityRestoreNetdevLabel(driver, vm, net) < 0) + VIR_WARN("Unable to restore security label on vhostuser char d= evice"); + } + qemuDomainNetDeviceVportRemove(net); =20 if (net->type =3D=3D VIR_DOMAIN_NET_TYPE_NETWORK) { diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c index e582a66071..19d957dd4b 100644 --- a/src/qemu/qemu_security.c +++ b/src/qemu/qemu_security.c @@ -439,6 +439,65 @@ qemuSecurityRestoreChardevLabel(virQEMUDriver *driver, return ret; } =20 +int +qemuSecuritySetNetdevLabel(virQEMUDriver *driver, + virDomainObj *vm, + virDomainNetDef *net) +{ + int ret =3D -1; + qemuDomainObjPrivate *priv =3D vm->privateData; + pid_t pid =3D -1; + + if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) + pid =3D vm->pid; + + if (virSecurityManagerTransactionStart(driver->securityManager) < 0) + goto cleanup; + + if (virSecurityManagerSetNetdevLabel(driver->securityManager, + vm->def, net) < 0) + goto cleanup; + + if (virSecurityManagerTransactionCommit(driver->securityManager, + pid, priv->rememberOwner) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + virSecurityManagerTransactionAbort(driver->securityManager); + return ret; +} + + +int +qemuSecurityRestoreNetdevLabel(virQEMUDriver *driver, + virDomainObj *vm, + virDomainNetDef *net) +{ + int ret =3D -1; + qemuDomainObjPrivate *priv =3D vm->privateData; + pid_t pid =3D -1; + + if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) + pid =3D vm->pid; + + if (virSecurityManagerTransactionStart(driver->securityManager) < 0) + goto cleanup; + + if (virSecurityManagerRestoreNetdevLabel(driver->securityManager, + vm->def, net) < 0) + goto cleanup; + + if (virSecurityManagerTransactionCommit(driver->securityManager, + pid, priv->rememberOwner) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + virSecurityManagerTransactionAbort(driver->securityManager); + return ret; +} + =20 /* * qemuSecurityStartVhostUserGPU: diff --git a/src/qemu/qemu_security.h b/src/qemu/qemu_security.h index 4c3d81e4b5..8b26ea3f99 100644 --- a/src/qemu/qemu_security.h +++ b/src/qemu/qemu_security.h @@ -79,6 +79,14 @@ int qemuSecurityRestoreChardevLabel(virQEMUDriver *drive= r, virDomainObj *vm, virDomainChrDef *chr); =20 +int qemuSecuritySetNetdevLabel(virQEMUDriver *driver, + virDomainObj *vm, + virDomainNetDef *net); + +int qemuSecurityRestoreNetdevLabel(virQEMUDriver *driver, + virDomainObj *vm, + virDomainNetDef *net); + int qemuSecurityStartVhostUserGPU(virQEMUDriver *driver, virDomainObj *vm, virCommand *cmd, diff --git a/src/security/security_apparmor.c b/src/security/security_appar= mor.c index 84363015dc..d942ea5005 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -1053,6 +1053,64 @@ AppArmorRestoreChardevLabel(virSecurityManager *mgr, return reload_profile(mgr, def, NULL, false); } =20 +static int +AppArmorSetNetdevLabel(virSecurityManager *mgr, + virDomainDef *def, + virDomainNetDef *net) +{ + int ret =3D -1; + virSecurityLabelDef *secdef; + virDomainChrSourceDef *dev_source; + virDomainNetType actualType; + + secdef =3D virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME= ); + if (!secdef) + return 0; + + actualType =3D virDomainNetGetActualType(net); + if (actualType !=3D VIR_DOMAIN_NET_TYPE_VHOSTUSER) + return 0; + + dev_source =3D net->data.vhostuser; + switch ((virDomainChrType)dev_source->type) { + case VIR_DOMAIN_CHR_TYPE_UNIX: + ret =3D reload_profile(mgr, def, dev_source->data.file.path, true); + break; + + case VIR_DOMAIN_CHR_TYPE_DEV: + case VIR_DOMAIN_CHR_TYPE_FILE: + case VIR_DOMAIN_CHR_TYPE_PTY: + case VIR_DOMAIN_CHR_TYPE_PIPE: + case VIR_DOMAIN_CHR_TYPE_SPICEPORT: + case VIR_DOMAIN_CHR_TYPE_NULL: + case VIR_DOMAIN_CHR_TYPE_VC: + case VIR_DOMAIN_CHR_TYPE_STDIO: + case VIR_DOMAIN_CHR_TYPE_UDP: + case VIR_DOMAIN_CHR_TYPE_TCP: + case VIR_DOMAIN_CHR_TYPE_SPICEVMC: + case VIR_DOMAIN_CHR_TYPE_NMDM: + case VIR_DOMAIN_CHR_TYPE_LAST: + ret =3D 0; + break; + } + + return ret; +} + +static int +AppArmorRestoreNetdevLabel(virSecurityManager *mgr, + virDomainDef *def, + virDomainNetDef *net G_GNUC_UNUSED) +{ + virSecurityLabelDef *secdef; + + secdef =3D virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME= ); + if (!secdef) + return 0; + + return reload_profile(mgr, def, NULL, false); +} + static int AppArmorSetPathLabel(virSecurityManager *mgr, virDomainDef *def, @@ -1168,6 +1226,9 @@ virSecurityDriver virAppArmorSecurityDriver =3D { .domainSetSecurityChardevLabel =3D AppArmorSetChardevLabel, .domainRestoreSecurityChardevLabel =3D AppArmorRestoreChardevLabel, =20 + .domainSetSecurityNetdevLabel =3D AppArmorSetNetdevLabel, + .domainRestoreSecurityNetdevLabel =3D AppArmorRestoreNetdevLabel, + .domainSetSecurityImageFDLabel =3D AppArmorSetFDLabel, .domainSetSecurityTapFDLabel =3D AppArmorSetFDLabel, =20 diff --git a/src/security/security_driver.h b/src/security/security_driver.h index 07f8def3d3..a1fc23be38 100644 --- a/src/security/security_driver.h +++ b/src/security/security_driver.h @@ -157,6 +157,12 @@ typedef int (*virSecurityDomainSetTPMLabels) (virSecur= ityManager *mgr, virDomainDef *def); typedef int (*virSecurityDomainRestoreTPMLabels) (virSecurityManager *mgr, virDomainDef *def); +typedef int (*virSecurityDomainSetNetdevLabel) (virSecurityManager *mgr, + virDomainDef *def, + virDomainNetDef *net); +typedef int (*virSecurityDomainRestoreNetdevLabel) (virSecurityManager *mg= r, + virDomainDef *def, + virDomainNetDef *net); =20 =20 struct _virSecurityDriver { @@ -224,6 +230,9 @@ struct _virSecurityDriver { =20 virSecurityDomainSetTPMLabels domainSetSecurityTPMLabels; virSecurityDomainRestoreTPMLabels domainRestoreSecurityTPMLabels; + + virSecurityDomainSetNetdevLabel domainSetSecurityNetdevLabel; + virSecurityDomainRestoreNetdevLabel domainRestoreSecurityNetdevLabel; }; =20 virSecurityDriver *virSecurityDriverLookup(const char *name, diff --git a/src/security/security_manager.c b/src/security/security_manage= r.c index 9906c1691d..d8a03a19cb 100644 --- a/src/security/security_manager.c +++ b/src/security/security_manager.c @@ -1297,6 +1297,44 @@ virSecurityManagerRestoreTPMLabels(virSecurityManage= r *mgr, } =20 =20 +int +virSecurityManagerSetNetdevLabel(virSecurityManager *mgr, + virDomainDef *vm, + virDomainNetDef *net) +{ + int ret; + + if (mgr->drv->domainSetSecurityNetdevLabel) { + virObjectLock(mgr); + ret =3D mgr->drv->domainSetSecurityNetdevLabel(mgr, vm, net); + virObjectUnlock(mgr); + + return ret; + } + + return 0; +} + + +int +virSecurityManagerRestoreNetdevLabel(virSecurityManager *mgr, + virDomainDef *vm, + virDomainNetDef *net) +{ + int ret; + + if (mgr->drv->domainRestoreSecurityNetdevLabel) { + virObjectLock(mgr); + ret =3D mgr->drv->domainRestoreSecurityNetdevLabel(mgr, vm, net); + virObjectUnlock(mgr); + + return ret; + } + + return 0; +} + + static int cmpstringp(const void *p1, const void *p2) { diff --git a/src/security/security_manager.h b/src/security/security_manage= r.h index 57047ccb13..59020b1475 100644 --- a/src/security/security_manager.h +++ b/src/security/security_manager.h @@ -220,6 +220,14 @@ int virSecurityManagerSetTPMLabels(virSecurityManager = *mgr, int virSecurityManagerRestoreTPMLabels(virSecurityManager *mgr, virDomainDef *vm); =20 +int virSecurityManagerSetNetdevLabel(virSecurityManager *mgr, + virDomainDef *vm, + virDomainNetDef *net); + +int virSecurityManagerRestoreNetdevLabel(virSecurityManager *mgr, + virDomainDef *vm, + virDomainNetDef *net); + typedef struct _virSecurityManagerMetadataLockState virSecurityManagerMeta= dataLockState; struct _virSecurityManagerMetadataLockState { size_t nfds; /* Captures size of both @fds and @paths */ diff --git a/src/security/security_stack.c b/src/security/security_stack.c index f7a9ed1e33..3c2239910a 100644 --- a/src/security/security_stack.c +++ b/src/security/security_stack.c @@ -963,6 +963,55 @@ virSecurityStackRestoreTPMLabels(virSecurityManager *m= gr, } =20 =20 +static int +virSecurityStackDomainSetNetdevLabel(virSecurityManager *mgr, + virDomainDef *def, + virDomainNetDef *net) +{ + virSecurityStackData *priv =3D virSecurityManagerGetPrivateData(mgr); + virSecurityStackItem *item =3D priv->itemsHead; + + for (; item; item =3D item->next) { + if (virSecurityManagerSetNetdevLabel(item->securityManager, def, n= et) < 0) + goto rollback; + } + + return 0; + + rollback: + for (item =3D item->prev; item; item =3D item->prev) { + if (virSecurityManagerRestoreNetdevLabel(item->securityManager, + def, net) < 0) { + VIR_WARN("Unable to restore netdev label after failed set labe= l " + "call virDriver=3D%s driver=3D%s domain=3D%s", + virSecurityManagerGetVirtDriver(mgr), + virSecurityManagerGetDriver(item->securityManager), + def->name); + } + } + return -1; +} + + +static int +virSecurityStackDomainRestoreNetdevLabel(virSecurityManager *mgr, + virDomainDef *def, + virDomainNetDef *net) +{ + virSecurityStackData *priv =3D virSecurityManagerGetPrivateData(mgr); + virSecurityStackItem *item =3D priv->itemsHead; + int rc =3D 0; + + for (; item; item =3D item->next) { + if (virSecurityManagerRestoreNetdevLabel(item->securityManager, + def, net) < 0) + rc =3D -1; + } + + return rc; +} + + virSecurityDriver virSecurityDriverStack =3D { .privateDataLen =3D sizeof(virSecurityStackData), .name =3D "stack", @@ -1028,4 +1077,7 @@ virSecurityDriver virSecurityDriverStack =3D { =20 .domainSetSecurityTPMLabels =3D virSecurityStackSetTPMLabels, .domainRestoreSecurityTPMLabels =3D virSecurityStackRestoreTPMLabe= ls, + + .domainSetSecurityNetdevLabel =3D virSecurityStackDomainSetNetdev= Label, + .domainRestoreSecurityNetdevLabel =3D virSecurityStackDomainRestoreNe= tdevLabel, }; --=20 2.32.0