Commit de139a33 authored by Chris Wright's avatar Chris Wright Committed by Greg Kroah-Hartman

pci: check caps from sysfs file open to read device dependent config space

The PCI config space bin_attr read handler has a hardcoded CAP_SYS_ADMIN
check to verify privileges before allowing a user to read device
dependent config space.  This is meant to protect from an unprivileged
user potentially locking up the box.

When assigning a PCI device directly to a guest with libvirt and KVM,
the sysfs config space file is chown'd to the unprivileged user that
the KVM guest will run as.  The guest needs to have full access to the
device's config space since it's responsible for driving the device.
However, despite being the owner of the sysfs file, the CAP_SYS_ADMIN
check will not allow read access beyond the config header.

With this patch we check privileges against the capabilities used when
openining the sysfs file.  The allows a privileged process to open the
file and hand it to an unprivileged process, and the unprivileged process
can still read all of the config space.
Signed-off-by: default avatarChris Wright <chrisw@sous-sol.org>
Acked-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 2c3c8bea
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/topology.h> #include <linux/topology.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/fs.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/pci-aspm.h> #include <linux/pci-aspm.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -367,7 +368,7 @@ pci_read_config(struct file *filp, struct kobject *kobj, ...@@ -367,7 +368,7 @@ pci_read_config(struct file *filp, struct kobject *kobj,
u8 *data = (u8*) buf; u8 *data = (u8*) buf;
/* Several chips lock up trying to read undefined config space */ /* Several chips lock up trying to read undefined config space */
if (capable(CAP_SYS_ADMIN)) { if (cap_raised(filp->f_cred->cap_effective, CAP_SYS_ADMIN)) {
size = dev->cfg_size; size = dev->cfg_size;
} else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
size = 128; size = 128;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment