debugfs: Add mode, uid and gid mount options; set default mode to 700 (Closes: #681418)

svn path=/dists/sid/linux/; revision=19294
This commit is contained in:
Ben Hutchings 2012-07-26 03:51:00 +00:00
parent aa7975939f
commit 3175cdc576
4 changed files with 244 additions and 0 deletions

2
debian/changelog vendored
View File

@ -37,6 +37,8 @@ linux (3.2.24-1) UNRELEASED; urgency=low
* udeb: Add snd-hda-codec-ca0132 to sound-modules (Closes: #682368)
* linux-source: Suggest pkg-config, needed to build kconfig GUIs
(Closes: #682726)
* debugfs: Add mode, uid and gid mount options; set default mode to 700
(Closes: #681418)
-- Ben Hutchings <ben@decadent.org.uk> Tue, 24 Jul 2012 02:20:37 +0100

View File

@ -0,0 +1,27 @@
From: Ben Hutchings <ben@decadent.org.uk>
Subject: debugfs: Set default mode to 700
Bug-Debian: http://bugs.debian.org/681418
As discussed here
<http://lists.linux-foundation.org/pipermail/ksummit-2012-discuss/2012-July/000891.html>.
Mounting of debugfs is a significant security liability, but there are
applications that depend on some interfaces based on debugfs and they
(or their packages) will mount it automatically anyway.
Setting the default mode for the debugfs root to 700 (accessible
to root only) should leave it functional, since most such applications
will require root anyway, and users can override it to relax
permissions if they really don't care about the security problems.
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -28,7 +28,7 @@
#include <linux/magic.h>
#include <linux/slab.h>
-#define DEBUGFS_DEFAULT_MODE 0755
+#define DEBUGFS_DEFAULT_MODE 0700
static struct vfsmount *debugfs_mount;
static int debugfs_mount_count;

View File

@ -0,0 +1,212 @@
From: Ludwig Nussel <ludwig.nussel@suse.de>
Date: Wed, 25 Jan 2012 11:52:28 +0100
Subject: debugfs: add mode, uid and gid options
commit d6e486868cde585842d55ba3b6ec57af090fc343 upstream.
Cautious admins may want to restrict access to debugfs. Currently a
manual chown/chmod e.g. in an init script is needed to achieve that.
Distributions that want to make the mount options configurable need
to add extra config files. By allowing to set the root inode's uid,
gid and mode via mount options no such hacks are needed anymore.
Instead configuration becomes straight forward via fstab.
Signed-off-by: Ludwig Nussel <ludwig.nussel@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
[bwh: Backported to 3.2: super_operations::show_options takes a
struct vfsmount *, not a struct dentry *]
---
Documentation/filesystems/debugfs.txt | 5 +-
fs/debugfs/inode.c | 149 ++++++++++++++++++++++++++++++++-
2 files changed, 152 insertions(+), 2 deletions(-)
diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt
index 6872c91..4e25758 100644
--- a/Documentation/filesystems/debugfs.txt
+++ b/Documentation/filesystems/debugfs.txt
@@ -14,7 +14,10 @@ Debugfs is typically mounted with a command like:
mount -t debugfs none /sys/kernel/debug
-(Or an equivalent /etc/fstab line).
+(Or an equivalent /etc/fstab line).
+The debugfs root directory is accessible by anyone by default. To
+restrict access to the tree the "uid", "gid" and "mode" mount
+options can be used.
Note that the debugfs API is exported GPL-only to modules.
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 956d5dd..b80bc84 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -23,9 +23,13 @@
#include <linux/debugfs.h>
#include <linux/fsnotify.h>
#include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/parser.h>
#include <linux/magic.h>
#include <linux/slab.h>
+#define DEBUGFS_DEFAULT_MODE 0755
+
static struct vfsmount *debugfs_mount;
static int debugfs_mount_count;
static bool debugfs_registered;
@@ -125,11 +129,154 @@ static inline int debugfs_positive(struct dentry *dentry)
return dentry->d_inode && !d_unhashed(dentry);
}
+struct debugfs_mount_opts {
+ uid_t uid;
+ gid_t gid;
+ umode_t mode;
+};
+
+enum {
+ Opt_uid,
+ Opt_gid,
+ Opt_mode,
+ Opt_err
+};
+
+static const match_table_t tokens = {
+ {Opt_uid, "uid=%u"},
+ {Opt_gid, "gid=%u"},
+ {Opt_mode, "mode=%o"},
+ {Opt_err, NULL}
+};
+
+struct debugfs_fs_info {
+ struct debugfs_mount_opts mount_opts;
+};
+
+static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts)
+{
+ substring_t args[MAX_OPT_ARGS];
+ int option;
+ int token;
+ char *p;
+
+ opts->mode = DEBUGFS_DEFAULT_MODE;
+
+ while ((p = strsep(&data, ",")) != NULL) {
+ if (!*p)
+ continue;
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_uid:
+ if (match_int(&args[0], &option))
+ return -EINVAL;
+ opts->uid = option;
+ break;
+ case Opt_gid:
+ if (match_octal(&args[0], &option))
+ return -EINVAL;
+ opts->gid = option;
+ break;
+ case Opt_mode:
+ if (match_octal(&args[0], &option))
+ return -EINVAL;
+ opts->mode = option & S_IALLUGO;
+ break;
+ /*
+ * We might like to report bad mount options here;
+ * but traditionally debugfs has ignored all mount options
+ */
+ }
+ }
+
+ return 0;
+}
+
+static int debugfs_apply_options(struct super_block *sb)
+{
+ struct debugfs_fs_info *fsi = sb->s_fs_info;
+ struct inode *inode = sb->s_root->d_inode;
+ struct debugfs_mount_opts *opts = &fsi->mount_opts;
+
+ inode->i_mode &= ~S_IALLUGO;
+ inode->i_mode |= opts->mode;
+
+ inode->i_uid = opts->uid;
+ inode->i_gid = opts->gid;
+
+ return 0;
+}
+
+static int debugfs_remount(struct super_block *sb, int *flags, char *data)
+{
+ int err;
+ struct debugfs_fs_info *fsi = sb->s_fs_info;
+
+ err = debugfs_parse_options(data, &fsi->mount_opts);
+ if (err)
+ goto fail;
+
+ debugfs_apply_options(sb);
+
+fail:
+ return err;
+}
+
+static int debugfs_show_options(struct seq_file *m, struct dentry *root)
+{
+ struct debugfs_fs_info *fsi = root->d_sb->s_fs_info;
+ struct debugfs_mount_opts *opts = &fsi->mount_opts;
+
+ if (opts->uid != 0)
+ seq_printf(m, ",uid=%u", opts->uid);
+ if (opts->gid != 0)
+ seq_printf(m, ",gid=%u", opts->gid);
+ if (opts->mode != DEBUGFS_DEFAULT_MODE)
+ seq_printf(m, ",mode=%o", opts->mode);
+
+ return 0;
+}
+
+static const struct super_operations debugfs_super_operations = {
+ .statfs = simple_statfs,
+ .remount_fs = debugfs_remount,
+ .show_options = debugfs_show_options,
+};
+
static int debug_fill_super(struct super_block *sb, void *data, int silent)
{
static struct tree_descr debug_files[] = {{""}};
+ struct debugfs_fs_info *fsi;
+ int err;
+
+ save_mount_options(sb, data);
+
+ fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL);
+ sb->s_fs_info = fsi;
+ if (!fsi) {
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ err = debugfs_parse_options(data, &fsi->mount_opts);
+ if (err)
+ goto fail;
+
+ err = simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
+ if (err)
+ goto fail;
+
+ sb->s_op = &debugfs_super_operations;
+
+ debugfs_apply_options(sb);
+
+ return 0;
- return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
+fail:
+ kfree(fsi);
+ sb->s_fs_info = NULL;
+ return err;
}
static struct dentry *debug_mount(struct file_system_type *fs_type,

View File

@ -365,3 +365,6 @@ debian/hrtimer-Avoid-ABI-change-in-3.2.24.patch
debian/net-Avoid-ABI-change-in-3.2.24.patch
debian/libsas-Avoid-ABI-change-in-3.2.24.patch
debian/powerpc-cputime-Avoid-ABI-change-in-3.2.24.patch
features/all/debugfs-add-mode-uid-and-gid-options.patch
debian/debugfs-set-default-mode-to-700.patch