Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp1237288ybi; Fri, 21 Jun 2019 17:05:13 -0700 (PDT) X-Google-Smtp-Source: APXvYqzSTAuerk631Ha8iKSsV/aDHru2esQHkvhqKz7A+ZNas1K7O+oMtks9Ur+zJohGUZxwrAfB X-Received: by 2002:a63:511b:: with SMTP id f27mr20705104pgb.135.1561161913754; Fri, 21 Jun 2019 17:05:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561161913; cv=none; d=google.com; s=arc-20160816; b=YaRUOfMEhY699y1pwJO+QkDBF3uFpBAxiApioVefhJ4uXZR3cobp/Kruo4wT7a9c6Q wXMszJu9d2RWfnEXU15p4Cq86epCJJvVwrfalduFVFqXoSArnQDHpCKiEckBb9IYYNyP 2+JeTkd/aGA76/T5gt05miK3VhCy9vYR3o7BTkEaIN4/wraWcFagBBPH6srKoSoMJOMS G6D46SClt24vCS+lcFdla/f0n25Jlg+31XeWR4Tb0nsK2ME1vajOnPQXPGSUxC2sPn1d 8I0ZfhYBoSsUSjjqAwk6HOlS7IgiXBkxdxzM/oVb6JqL8iha7LxYIjCEWa3IwEdDakwQ kjsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=QR1Fq3MnogoZDxR5LoHcfLT1JRgAByQ+Bas4Z8/9Vdo=; b=N9ktMj4dWbNZfy7+B/o1wSct9nQklGB738uDeeKInBTbaLfZUzO4JXt4xsufCvUXLv zZTFY6J05VVcDPWfbZ4Xdz+yuUfwMHe9t1oVMFjWJDGlQhi0MD/rJsSAewQ1W/ZcI65j Q5XguVjwBQlQa6II3LnmBWwkzrTw7BBbZQqMkiLOrx58zP6cMBlJJz6quOnyjMmRzIP0 tcnVcL6nCD5rZZd1/uFyJY/xtxxb/fYWRWS4+vEOg1kQFWIMsUHbE02KvaXwC4ynFp+m Sg1ImN1ibsFSiaJOs9lMIQxH5XE9WwjDf5eWjZCLYnkFiocEgKozf3g0aO+fQDSWxRgt n89A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=cfhgJlRM; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 33si4151462ply.10.2019.06.21.17.04.58; Fri, 21 Jun 2019 17:05:13 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=cfhgJlRM; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726688AbfFVAEc (ORCPT + 99 others); Fri, 21 Jun 2019 20:04:32 -0400 Received: from mail-qt1-f201.google.com ([209.85.160.201]:47277 "EHLO mail-qt1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726656AbfFVAEa (ORCPT ); Fri, 21 Jun 2019 20:04:30 -0400 Received: by mail-qt1-f201.google.com with SMTP id s9so9775949qtn.14 for ; Fri, 21 Jun 2019 17:04:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=QR1Fq3MnogoZDxR5LoHcfLT1JRgAByQ+Bas4Z8/9Vdo=; b=cfhgJlRMYlL1ZQu+27acnf30xFuMCjbXTCAainFoeEtW6sZfy4z78AwyGDy66Snw59 pvtbyWjFtVqv2AKhiP7OGS07Od6EaserX0vCQ10ANdg4TLN7ndS3gF8OdAbzxSMsZSjY sgeyCW+DZbTYK5bDNnjil5OmnI6NDxkWpYVsoDss5Tq0elODK37VxHU4y9hCNubVo7H9 D6Jc4/affqcgrEdydVrRLwyNXiUAVcnoLZVmNAKzcNEAxu/tKT5a4J7pWmeE/G0DMrk1 UjiODKe8fvrl0qgaiKwOCtBZVX6C122MMiRCGRrT/OHEGYG0c08Il4sj/O4286/d7H/A e7rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=QR1Fq3MnogoZDxR5LoHcfLT1JRgAByQ+Bas4Z8/9Vdo=; b=UrRlHspKua2BVMuWLVVYhX2lSLK374OHZ5fF9/DEQW9pBQfStu/beyn+VSzGKvi20e ztGTZvXryjERQ3F8Bv1nyyosW7d0MAJ4pfl9DF6tQUYUSZmF5X8oneqP9vXYRXWj+tJQ ZSdcTw3VwMrgVUK2dPzmPvZqmPLQuYg7metzdqDTprOozz8Pb+A4xgufUP1+bmopwPjc KpmsD51IwRnRsOxXEkGKo7bAqe6SuraF1YGFpIMLD2Xpsf90vhgSeHZr/8yru1c2i/Q+ LkzV+YmKqFUDneQ5aIQyNvm7/3GEqf4cR50ZgN4Q+05ZOIUmZh3Y3UwnhmZ70Mffbao0 BL5w== X-Gm-Message-State: APjAAAVXucZS7trsMpQ4HfRsSLt2nMzOWyvfrh0AAnUlNKla2qTf6tUT kVwWEos++m5ClE24rlC3JNlTPhxpEFw39C/PrDrpwA== X-Received: by 2002:a37:a98c:: with SMTP id s134mr109806733qke.176.1561161869518; Fri, 21 Jun 2019 17:04:29 -0700 (PDT) Date: Fri, 21 Jun 2019 17:03:40 -0700 In-Reply-To: <20190622000358.19895-1-matthewgarrett@google.com> Message-Id: <20190622000358.19895-12-matthewgarrett@google.com> Mime-Version: 1.0 References: <20190622000358.19895-1-matthewgarrett@google.com> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog Subject: [PATCH V34 11/29] PCI: Lock down BAR access when the kernel is locked down From: Matthew Garrett To: jmorris@namei.org Cc: linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, Matthew Garrett , David Howells , Matthew Garrett , Bjorn Helgaas , linux-pci@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Matthew Garrett Any hardware that can potentially generate DMA has to be locked down in order to avoid it being possible for an attacker to modify kernel code, allowing them to circumvent disabled module loading or module signing. Default to paranoid - in future we can potentially relax this for sufficiently IOMMU-isolated devices. Signed-off-by: David Howells Signed-off-by: Matthew Garrett Acked-by: Bjorn Helgaas cc: linux-pci@vger.kernel.org --- drivers/pci/pci-sysfs.c | 16 ++++++++++++++++ drivers/pci/proc.c | 14 ++++++++++++-- drivers/pci/syscall.c | 4 +++- include/linux/security.h | 1 + security/lockdown/lockdown.c | 1 + 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 25794c27c7a4..e1011efb5a31 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -903,6 +903,11 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj, unsigned int size = count; loff_t init_off = off; u8 *data = (u8 *) buf; + int ret; + + ret = security_locked_down(LOCKDOWN_PCI_ACCESS); + if (ret) + return ret; if (off > dev->cfg_size) return 0; @@ -1165,6 +1170,11 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, int bar = (unsigned long)attr->private; enum pci_mmap_state mmap_type; struct resource *res = &pdev->resource[bar]; + int ret; + + ret = security_locked_down(LOCKDOWN_PCI_ACCESS); + if (ret) + return ret; if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start)) return -EINVAL; @@ -1241,6 +1251,12 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { + int ret; + + ret = security_locked_down(LOCKDOWN_PCI_ACCESS); + if (ret) + return ret; + return pci_resource_io(filp, kobj, attr, buf, off, count, true); } diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 6fa1627ce08d..a72258d70407 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "pci.h" @@ -115,7 +116,11 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf, struct pci_dev *dev = PDE_DATA(ino); int pos = *ppos; int size = dev->cfg_size; - int cnt; + int cnt, ret; + + ret = security_locked_down(LOCKDOWN_PCI_ACCESS); + if (ret) + return ret; if (pos >= size) return 0; @@ -196,6 +201,10 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd, #endif /* HAVE_PCI_MMAP */ int ret = 0; + ret = security_locked_down(LOCKDOWN_PCI_ACCESS); + if (ret) + return ret; + switch (cmd) { case PCIIOC_CONTROLLER: ret = pci_domain_nr(dev->bus); @@ -237,7 +246,8 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) struct pci_filp_private *fpriv = file->private_data; int i, ret, write_combine = 0, res_bit = IORESOURCE_MEM; - if (!capable(CAP_SYS_RAWIO)) + if (!capable(CAP_SYS_RAWIO) || + security_locked_down(LOCKDOWN_PCI_ACCESS)) return -EPERM; if (fpriv->mmap_state == pci_mmap_io) { diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c index d96626c614f5..31e39558d49d 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include "pci.h" @@ -90,7 +91,8 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn, u32 dword; int err = 0; - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) || + security_locked_down(LOCKDOWN_PCI_ACCESS)) return -EPERM; dev = pci_get_domain_bus_and_slot(0, bus, dfn); diff --git a/include/linux/security.h b/include/linux/security.h index a051f21a1144..1b849f10dec6 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -86,6 +86,7 @@ enum lockdown_reason { LOCKDOWN_DEV_MEM, LOCKDOWN_KEXEC, LOCKDOWN_HIBERNATION, + LOCKDOWN_PCI_ACCESS, LOCKDOWN_INTEGRITY_MAX, LOCKDOWN_CONFIDENTIALITY_MAX, }; diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c index ce5b3da9bd09..e2ee8a16b94c 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -22,6 +22,7 @@ static char *lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = { [LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port", [LOCKDOWN_KEXEC] = "kexec of unsigned images", [LOCKDOWN_HIBERNATION] = "hibernation", + [LOCKDOWN_PCI_ACCESS] = "direct PCI access", [LOCKDOWN_INTEGRITY_MAX] = "integrity", [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality", }; -- 2.22.0.410.gd8fdbe21b5-goog