summaryrefslogtreecommitdiffstats
path: root/fs/debugfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/debugfs/file.c')
-rw-r--r--fs/debugfs/file.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 93e4ca6b2ad7..87846aad594b 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -19,6 +19,7 @@
19#include <linux/atomic.h> 19#include <linux/atomic.h>
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/poll.h> 21#include <linux/poll.h>
22#include <linux/security.h>
22 23
23#include "internal.h" 24#include "internal.h"
24 25
@@ -136,6 +137,25 @@ void debugfs_file_put(struct dentry *dentry)
136} 137}
137EXPORT_SYMBOL_GPL(debugfs_file_put); 138EXPORT_SYMBOL_GPL(debugfs_file_put);
138 139
140/*
141 * Only permit access to world-readable files when the kernel is locked down.
142 * We also need to exclude any file that has ways to write or alter it as root
143 * can bypass the permissions check.
144 */
145static bool debugfs_is_locked_down(struct inode *inode,
146 struct file *filp,
147 const struct file_operations *real_fops)
148{
149 if ((inode->i_mode & 07777) == 0444 &&
150 !(filp->f_mode & FMODE_WRITE) &&
151 !real_fops->unlocked_ioctl &&
152 !real_fops->compat_ioctl &&
153 !real_fops->mmap)
154 return false;
155
156 return security_locked_down(LOCKDOWN_DEBUGFS);
157}
158
139static int open_proxy_open(struct inode *inode, struct file *filp) 159static int open_proxy_open(struct inode *inode, struct file *filp)
140{ 160{
141 struct dentry *dentry = F_DENTRY(filp); 161 struct dentry *dentry = F_DENTRY(filp);
@@ -147,6 +167,11 @@ static int open_proxy_open(struct inode *inode, struct file *filp)
147 return r == -EIO ? -ENOENT : r; 167 return r == -EIO ? -ENOENT : r;
148 168
149 real_fops = debugfs_real_fops(filp); 169 real_fops = debugfs_real_fops(filp);
170
171 r = debugfs_is_locked_down(inode, filp, real_fops);
172 if (r)
173 goto out;
174
150 real_fops = fops_get(real_fops); 175 real_fops = fops_get(real_fops);
151 if (!real_fops) { 176 if (!real_fops) {
152 /* Huh? Module did not clean up after itself at exit? */ 177 /* 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)
272 return r == -EIO ? -ENOENT : r; 297 return r == -EIO ? -ENOENT : r;
273 298
274 real_fops = debugfs_real_fops(filp); 299 real_fops = debugfs_real_fops(filp);
300
301 r = debugfs_is_locked_down(inode, filp, real_fops);
302 if (r)
303 goto out;
304
275 real_fops = fops_get(real_fops); 305 real_fops = fops_get(real_fops);
276 if (!real_fops) { 306 if (!real_fops) {
277 /* Huh? Module did not cleanup after itself at exit? */ 307 /* Huh? Module did not cleanup after itself at exit? */