--- /dev/null
+From a628e7b87e100befac9702aa0c3b9848a7685e49 Mon Sep 17 00:00:00 2001
+From: Chris Wright <chrisw@sous-sol.org>
+Date: Mon, 14 Feb 2011 17:21:49 -0800
+Subject: pci: use security_capable() when checking capablities during config space read
+
+From: Chris Wright <chrisw@sous-sol.org>
+
+commit a628e7b87e100befac9702aa0c3b9848a7685e49 upstream.
+
+This reintroduces commit 47970b1b which was subsequently reverted
+as f00eaeea. The original change was broken and caused X startup
+failures and generally made privileged processes incapable of reading
+device dependent config space. The normal capable() interface returns
+true on success, but the LSM interface returns 0 on success. This thinko
+is now fixed in this patch, and has been confirmed to work properly.
+
+So, once again...Eric Paris noted that commit de139a3 ("pci: check caps
+from sysfs file open to read device dependent config space") caused the
+capability check to bypass security modules and potentially auditing.
+Rectify this by calling security_capable() when checking the open file's
+capabilities for config space reads.
+
+Reported-by: Eric Paris <eparis@redhat.com>
+Tested-by: Dave Young <hidave.darkstar@gmail.com>
+Acked-by: James Morris <jmorris@namei.org>
+Cc: Dave Airlie <airlied@gmail.com>
+Cc: Alex Riesen <raa.lkml@gmail.com>
+Cc: Sedat Dilek <sedat.dilek@googlemail.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: James Morris <jmorris@namei.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/pci-sysfs.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/pci/pci-sysfs.c
++++ b/drivers/pci/pci-sysfs.c
+@@ -23,6 +23,7 @@
+ #include <linux/mm.h>
+ #include <linux/fs.h>
+ #include <linux/capability.h>
++#include <linux/security.h>
+ #include <linux/pci-aspm.h>
+ #include <linux/slab.h>
+ #include "pci.h"
+@@ -368,7 +369,7 @@ pci_read_config(struct file *filp, struc
+ u8 *data = (u8*) buf;
+
+ /* Several chips lock up trying to read undefined config space */
+- if (cap_raised(filp->f_cred->cap_effective, CAP_SYS_ADMIN)) {
++ if (security_capable(filp->f_cred, CAP_SYS_ADMIN) == 0) {
+ size = dev->cfg_size;
+ } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
+ size = 128;
--- /dev/null
+From 6037b715d6fab139742c3df8851db4c823081561 Mon Sep 17 00:00:00 2001
+From: Chris Wright <chrisw@sous-sol.org>
+Date: Wed, 9 Feb 2011 22:11:51 -0800
+Subject: security: add cred argument to security_capable()
+
+From: Chris Wright <chrisw@sous-sol.org>
+
+commit 6037b715d6fab139742c3df8851db4c823081561 upstream.
+
+Expand security_capable() to include cred, so that it can be usable in a
+wider range of call sites.
+
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
+Signed-off-by: James Morris <jmorris@namei.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/security.h | 6 +++---
+ kernel/capability.c | 2 +-
+ security/security.c | 5 ++---
+ 3 files changed, 6 insertions(+), 7 deletions(-)
+
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -1664,7 +1664,7 @@ int security_capset(struct cred *new, co
+ const kernel_cap_t *effective,
+ const kernel_cap_t *inheritable,
+ const kernel_cap_t *permitted);
+-int security_capable(int cap);
++int security_capable(const struct cred *cred, int cap);
+ int security_real_capable(struct task_struct *tsk, int cap);
+ int security_real_capable_noaudit(struct task_struct *tsk, int cap);
+ int security_sysctl(struct ctl_table *table, int op);
+@@ -1857,9 +1857,9 @@ static inline int security_capset(struct
+ return cap_capset(new, old, effective, inheritable, permitted);
+ }
+
+-static inline int security_capable(int cap)
++static inline int security_capable(const struct cred *cred, int cap)
+ {
+- return cap_capable(current, current_cred(), cap, SECURITY_CAP_AUDIT);
++ return cap_capable(current, cred, cap, SECURITY_CAP_AUDIT);
+ }
+
+ static inline int security_real_capable(struct task_struct *tsk, int cap)
+--- a/kernel/capability.c
++++ b/kernel/capability.c
+@@ -306,7 +306,7 @@ int capable(int cap)
+ BUG();
+ }
+
+- if (security_capable(cap) == 0) {
++ if (security_capable(current_cred(), cap) == 0) {
+ current->flags |= PF_SUPERPRIV;
+ return 1;
+ }
+--- a/security/security.c
++++ b/security/security.c
+@@ -154,10 +154,9 @@ int security_capset(struct cred *new, co
+ effective, inheritable, permitted);
+ }
+
+-int security_capable(int cap)
++int security_capable(const struct cred *cred, int cap)
+ {
+- return security_ops->capable(current, current_cred(), cap,
+- SECURITY_CAP_AUDIT);
++ return security_ops->capable(current, cred, cap, SECURITY_CAP_AUDIT);
+ }
+
+ int security_real_capable(struct task_struct *tsk, int cap)