Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp336764pxj; Fri, 7 May 2021 09:41:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw+ZAjmhxs/U04KfiS0f7VcEgei3cUEc9Dymdxb+djPDZUIwnMLCzqa/p+roKDdp1Y5GH3B X-Received: by 2002:a17:90a:d24a:: with SMTP id o10mr23972133pjw.138.1620405682555; Fri, 07 May 2021 09:41:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620405682; cv=none; d=google.com; s=arc-20160816; b=CG/d0/xwwPMtRwON8HDZQUD0m8ao8imHIwieSOQM93dSv4YL3Y9DABCTeYg+yRI9sL XuJdpdLz+2kLtkYKBwSrfnEOLbMnzrFTliOgU6+ILSRmM4CSxPaR/UOy1WoHrGNVqgtL OOVzYAuUrMuAPqWKA1f8retYelBMd0zkKCH8XpRQJjS3TQbpCZywCDIGO3g86hX/4ko7 onmxJbMhd3+fy1toGU80aNw7GAo6V7y4RLkhfF91K4xZ9k8E3DG2SC6uD/EIZWs6iurn cQUD8Bq2gnBB3XJzyzMJW9AF83odzaXQtDOlgHMm2Giv85kn7Px0DFdkke8N12Gk0E07 uYWA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=8ZWnxuhYP/znADIXvr0zXi06seVsXloJf8ocVnr0GQY=; b=kJE22FsOeBG0GHEYlMJ2FOpjBi1qBPSr2UHgjSndnsJFg3Xhf90pevkAnJNMqqqqyF iZcwZwNM2xSiTs39eL2xadIasNkJVAu2GxZzMtgNqHkib8+IqAwnxbzWGzgeYRBCpxDQ VWo0IN69Zex2eEYSXEpiOPC38pcOyGVykmmwpEV1VfVpiCHHz2plIs10k4QCyodL10Tg 6Gr+X0+pANvA2baWkPWrBo+fHvU7oFRPJvudxh8ppceBkQlqwbxf8Q/Lvv0V3ComVv7Q K7V7gTbHw6SJIE2HbWKjtuydmoofsQELV7gLVahktdLY9BfRjvvn2924T+VeyDHoxkBY vR8A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="e/yzdViA"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d2si16776785pjk.118.2021.05.07.09.41.09; Fri, 07 May 2021 09:41:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="e/yzdViA"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236988AbhEGMcq (ORCPT + 99 others); Fri, 7 May 2021 08:32:46 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:48862 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236687AbhEGMcq (ORCPT ); Fri, 7 May 2021 08:32:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1620390706; 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: in-reply-to:in-reply-to:references:references; bh=8ZWnxuhYP/znADIXvr0zXi06seVsXloJf8ocVnr0GQY=; b=e/yzdViAJXmkfLPTJqevDnaxATAOU3TmHinOvXet2LnpBRNRM8zXzUSKcYpNJVdK/qZUAT YgJttQoWHRWOTpONhcjzyDj3KkXfBWlkr+5jDbtH5t1ipeET1sCtdeg4UAdApdWa03W2Bx f91sZODyHQVmIBylyJmE2NNhKJs88J0= Received: from mail-yb1-f199.google.com (mail-yb1-f199.google.com [209.85.219.199]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-404-wD25ZkV2O--1cqsI80aIjw-1; Fri, 07 May 2021 08:31:42 -0400 X-MC-Unique: wD25ZkV2O--1cqsI80aIjw-1 Received: by mail-yb1-f199.google.com with SMTP id u3-20020a2509430000b02904e7f1a30cffso9833262ybm.8 for ; Fri, 07 May 2021 05:31:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=8ZWnxuhYP/znADIXvr0zXi06seVsXloJf8ocVnr0GQY=; b=LmAEP1VljgjpNtKio67NzxGd5iNpLY+ypvWApgBma5G7AjHjP7BncA3vwLiiOoEDLu RPfbxHXfHLHtDsUJZgdLhWwJvj9AlqzH2qyF+QH5FV6WNTJObDGvRi5rtH8pTc+X1+K7 2xkAToDMtuHwkVzjm6l9MNcCYAwXwcnZAASsxyH7WQnCpIK/GiqvvMKggFG/J6bj1336 Tirs8+l3jFIvEieH3LytzlD//e2lCwG1Rp28Er+wca35l5DDQGZHCHRaSlem02Du2WcY Ol7otvQh8E8sT4wLT+TlT6OEl1XZ9T+4sPxPq/zcLoVRL/UDxuNz/l24S7+OcH/7zL4F YMpg== X-Gm-Message-State: AOAM533dr1wWeCt/YihfaM/XTESW5WLgK2XdkrX5wygEIf/E5cmBlAxn RdmyqLy147727AVjh3tEkwTuiJT2nhdjzmNX35arryVZWwm1go+4KkdRctpAFIALdztLqP+EbLa m2Bvc1MsNIuN5a61WLIaHB4IRf57c1bSiIPZ/CMGF X-Received: by 2002:a25:6886:: with SMTP id d128mr13040351ybc.227.1620390702163; Fri, 07 May 2021 05:31:42 -0700 (PDT) X-Received: by 2002:a25:6886:: with SMTP id d128mr13040312ybc.227.1620390701899; Fri, 07 May 2021 05:31:41 -0700 (PDT) MIME-Version: 1.0 References: <20210506091859.6961-1-maxime.coquelin@redhat.com> <20210506155004.7e214d8f@redhat.com> In-Reply-To: From: Ondrej Mosnacek Date: Fri, 7 May 2021 14:31:28 +0200 Message-ID: Subject: Re: [PATCH] vfio: Lock down no-IOMMU mode when kernel is locked down To: Maxime Coquelin Cc: Alex Williamson , James Morris , David Howells , Linux kernel mailing list , Linux Security Module list , kvm@vger.kernel.org, mjg59@srcf.ucam.org, Kees Cook , Cornelia Huck , Paul Moore , Stephen Smalley , SElinux list Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org (Adding the SELinux list, Paul, and Stephen to Cc) On Fri, May 7, 2021 at 11:11 AM Maxime Coquelin wrote: > On 5/7/21 10:37 AM, Ondrej Mosnacek wrote: > > On Thu, May 6, 2021 at 11:50 PM Alex Williamson > > wrote: > >> On Thu, 6 May 2021 11:18:59 +0200 > >> Maxime Coquelin wrote: > >> > >>> When no-IOMMU mode is enabled, VFIO is as unsafe as accessing > >>> the PCI BARs via the device's sysfs, which is locked down when > >>> the kernel is locked down. > >>> > >>> Indeed, it is possible for an attacker to craft DMA requests > >>> to modify kernel's code or leak secrets stored in the kernel, > >>> since the device is not isolated by an IOMMU. > >>> > >>> This patch introduces a new integrity lockdown reason for the > >>> unsafe VFIO no-iommu mode. > >> > >> I'm hoping security folks will chime in here as I'm not familiar with > >> the standard practices for new lockdown reasons. The vfio no-iommu > >> backend is clearly an integrity risk, which is why it's already hidden > >> behind a separate Kconfig option, requires RAWIO capabilities, and > >> taints the kernel if it's used, but I agree that preventing it during > >> lockdown seems like a good additional step. > >> > >> Is it generally advised to create specific reasons, like done here, or > >> should we aim to create a more generic reason related to unrestricted > >> userspace DMA? > > I am fine with a more generic reason. I'm also not sure what is the best > thing to do in term of granularity. > > >> I understand we don't want to re-use PCI_ACCESS because the vfio > >> no-iommu backend is device agnostic, it can be used for both PCI and > >> non-PCI devices. > > Right, that's why I created a new reason. > > >>> Signed-off-by: Maxime Coquelin > >>> --- > >>> drivers/vfio/vfio.c | 13 +++++++++---- > >>> include/linux/security.h | 1 + > >>> security/security.c | 1 + > >>> 3 files changed, 11 insertions(+), 4 deletions(-) > >>> > >>> diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c > >>> index 5e631c359ef2..fe466d6ea5d8 100644 > >>> --- a/drivers/vfio/vfio.c > >>> +++ b/drivers/vfio/vfio.c > >>> @@ -25,6 +25,7 @@ > >>> #include > >>> #include > >>> #include > >>> +#include > >>> #include > >>> #include > >>> #include > >>> @@ -165,7 +166,8 @@ static void *vfio_noiommu_open(unsigned long arg) > >>> { > >>> if (arg != VFIO_NOIOMMU_IOMMU) > >>> return ERR_PTR(-EINVAL); > >>> - if (!capable(CAP_SYS_RAWIO)) > >>> + if (!capable(CAP_SYS_RAWIO) || > >>> + security_locked_down(LOCKDOWN_VFIO_NOIOMMU)) > >>> return ERR_PTR(-EPERM); > >>> > >>> return NULL; > >>> @@ -1280,7 +1282,8 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) > >>> if (atomic_read(&group->container_users)) > >>> return -EINVAL; > >>> > >>> - if (group->noiommu && !capable(CAP_SYS_RAWIO)) > >>> + if (group->noiommu && (!capable(CAP_SYS_RAWIO) || > >>> + security_locked_down(LOCKDOWN_VFIO_NOIOMMU))) > >>> return -EPERM; > >>> > >>> f = fdget(container_fd); > >>> @@ -1362,7 +1365,8 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) > >>> !group->container->iommu_driver || !vfio_group_viable(group)) > >>> return -EINVAL; > >>> > >>> - if (group->noiommu && !capable(CAP_SYS_RAWIO)) > >>> + if (group->noiommu && (!capable(CAP_SYS_RAWIO) || > >>> + security_locked_down(LOCKDOWN_VFIO_NOIOMMU))) > >>> return -EPERM; > >>> > >>> device = vfio_device_get_from_name(group, buf); > >>> @@ -1490,7 +1494,8 @@ static int vfio_group_fops_open(struct inode *inode, struct file *filep) > >>> if (!group) > >>> return -ENODEV; > >>> > >>> - if (group->noiommu && !capable(CAP_SYS_RAWIO)) { > >>> + if (group->noiommu && (!capable(CAP_SYS_RAWIO) || > >>> + security_locked_down(LOCKDOWN_VFIO_NOIOMMU))) { > >>> vfio_group_put(group); > >>> return -EPERM; > >>> } > >> > >> In these cases where we're testing RAWIO, the idea is to raise the > >> barrier of passing file descriptors to unprivileged users. Is lockdown > >> sufficiently static that we might really only need the test on open? > >> The latter three cases here only make sense if the user were able to > >> open a no-iommu context when lockdown is not enabled, then lockdown is > >> later enabled preventing them from doing anything with that context... > >> but not preventing ongoing unsafe usage that might already exist. I > >> suspect for that reason that lockdown is static and we really only need > >> the test on open. Thanks, > > > > Note that SELinux now also implements the locked_down hook and that > > implementation is not static like the Lockdown LSM's. It checks > > whether the current task's SELinux domain has either integrity or > > confidentiality permission granted by the policy, so for SELinux it > > makes sense to have the lockdown hook called in these other places as > > well. > > > > Thanks Ondrej for the insights, is there any plan for selinux to support > finer granularity than integrity and confidentiality? I'm not sure it > makes sense, but it might help to understand if we should choose between > a "VFIO no-iommu mode" reason and a more generic userspace DMA one. Looking at the ML discussion under the original patch posting [1], having a finer granularity was preferred, but there was a concern that the list of reasons would change too much, making the kernel <-> policy interface too unstable. Looking at the git log, the list of lockdown reasons hasn't changed much since the original SELinux implementation was added (there was just one addition, not counting this patch), so it looks like switching SELinux to finer granularity would be viable now. I'm not sure whether the less or more generic variant would be better here... Perhaps Stephen or Paul will have an opinion. [1] https://lore.kernel.org/selinux/365ca063-6efd-8051-8d4b-5c8aef0d2e12@tycho.nsa.gov/T/ -- Ondrej Mosnacek Software Engineer, Linux Security - SELinux kernel Red Hat, Inc.