summaryrefslogtreecommitdiffstats
path: root/fs/debugfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/debugfs/inode.c')
-rw-r--r--fs/debugfs/inode.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 042b688ed124..7b975dbb2bb4 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -26,6 +26,7 @@
26#include <linux/parser.h> 26#include <linux/parser.h>
27#include <linux/magic.h> 27#include <linux/magic.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/security.h>
29 30
30#include "internal.h" 31#include "internal.h"
31 32
@@ -35,6 +36,32 @@ static struct vfsmount *debugfs_mount;
35static int debugfs_mount_count; 36static int debugfs_mount_count;
36static bool debugfs_registered; 37static bool debugfs_registered;
37 38
39/*
40 * Don't allow access attributes to be changed whilst the kernel is locked down
41 * so that we can use the file mode as part of a heuristic to determine whether
42 * to lock down individual files.
43 */
44static int debugfs_setattr(struct dentry *dentry, struct iattr *ia)
45{
46 int ret = security_locked_down(LOCKDOWN_DEBUGFS);
47
48 if (ret && (ia->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
49 return ret;
50 return simple_setattr(dentry, ia);
51}
52
53static const struct inode_operations debugfs_file_inode_operations = {
54 .setattr = debugfs_setattr,
55};
56static const struct inode_operations debugfs_dir_inode_operations = {
57 .lookup = simple_lookup,
58 .setattr = debugfs_setattr,
59};
60static const struct inode_operations debugfs_symlink_inode_operations = {
61 .get_link = simple_get_link,
62 .setattr = debugfs_setattr,
63};
64
38static struct inode *debugfs_get_inode(struct super_block *sb) 65static struct inode *debugfs_get_inode(struct super_block *sb)
39{ 66{
40 struct inode *inode = new_inode(sb); 67 struct inode *inode = new_inode(sb);
@@ -369,6 +396,7 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
369 inode->i_mode = mode; 396 inode->i_mode = mode;
370 inode->i_private = data; 397 inode->i_private = data;
371 398
399 inode->i_op = &debugfs_file_inode_operations;
372 inode->i_fop = proxy_fops; 400 inode->i_fop = proxy_fops;
373 dentry->d_fsdata = (void *)((unsigned long)real_fops | 401 dentry->d_fsdata = (void *)((unsigned long)real_fops |
374 DEBUGFS_FSDATA_IS_REAL_FOPS_BIT); 402 DEBUGFS_FSDATA_IS_REAL_FOPS_BIT);
@@ -532,7 +560,7 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
532 } 560 }
533 561
534 inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; 562 inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
535 inode->i_op = &simple_dir_inode_operations; 563 inode->i_op = &debugfs_dir_inode_operations;
536 inode->i_fop = &simple_dir_operations; 564 inode->i_fop = &simple_dir_operations;
537 565
538 /* directory inodes start off with i_nlink == 2 (for "." entry) */ 566 /* directory inodes start off with i_nlink == 2 (for "." entry) */
@@ -632,7 +660,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
632 return failed_creating(dentry); 660 return failed_creating(dentry);
633 } 661 }
634 inode->i_mode = S_IFLNK | S_IRWXUGO; 662 inode->i_mode = S_IFLNK | S_IRWXUGO;
635 inode->i_op = &simple_symlink_inode_operations; 663 inode->i_op = &debugfs_symlink_inode_operations;
636 inode->i_link = link; 664 inode->i_link = link;
637 d_instantiate(dentry, inode); 665 d_instantiate(dentry, inode);
638 return end_creating(dentry); 666 return end_creating(dentry);