ALSA: hda - Fix pending unsol events at shutdown
[linux-2.6-block.git] / fs / debugfs / file.c
index 93e4ca6b2ad7a9185cefc973d2240dccd3441313..87846aad594b70ec06d6437b9c9bd3e56b6b43fd 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/atomic.h>
 #include <linux/device.h>
 #include <linux/poll.h>
+#include <linux/security.h>
 
 #include "internal.h"
 
@@ -136,6 +137,25 @@ void debugfs_file_put(struct dentry *dentry)
 }
 EXPORT_SYMBOL_GPL(debugfs_file_put);
 
+/*
+ * Only permit access to world-readable files when the kernel is locked down.
+ * We also need to exclude any file that has ways to write or alter it as root
+ * can bypass the permissions check.
+ */
+static bool debugfs_is_locked_down(struct inode *inode,
+                                  struct file *filp,
+                                  const struct file_operations *real_fops)
+{
+       if ((inode->i_mode & 07777) == 0444 &&
+           !(filp->f_mode & FMODE_WRITE) &&
+           !real_fops->unlocked_ioctl &&
+           !real_fops->compat_ioctl &&
+           !real_fops->mmap)
+               return false;
+
+       return security_locked_down(LOCKDOWN_DEBUGFS);
+}
+
 static int open_proxy_open(struct inode *inode, struct file *filp)
 {
        struct dentry *dentry = F_DENTRY(filp);
@@ -147,6 +167,11 @@ static int open_proxy_open(struct inode *inode, struct file *filp)
                return r == -EIO ? -ENOENT : r;
 
        real_fops = debugfs_real_fops(filp);
+
+       r = debugfs_is_locked_down(inode, filp, real_fops);
+       if (r)
+               goto out;
+
        real_fops = fops_get(real_fops);
        if (!real_fops) {
                /* Huh? Module did not clean up after itself at exit? */
@@ -272,6 +297,11 @@ static int full_proxy_open(struct inode *inode, struct file *filp)
                return r == -EIO ? -ENOENT : r;
 
        real_fops = debugfs_real_fops(filp);
+
+       r = debugfs_is_locked_down(inode, filp, real_fops);
+       if (r)
+               goto out;
+
        real_fops = fops_get(real_fops);
        if (!real_fops) {
                /* Huh? Module did not cleanup after itself at exit? */