staging/lustre/libcfs: Properly handle debugfs read- and write-only files
authorOleg Drokin <green@linuxhacker.ru>
Sat, 6 Feb 2016 07:01:50 +0000 (02:01 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 8 Feb 2016 01:34:58 +0000 (17:34 -0800)
It turns out that unlike procfs, debugfs does not really enforce
permissions for root (similar to regular filesystems), so we need
to ensure we are not providing ->write() method to read-only files
and ->read() method for write-only files at registration.

This fixes a couple of crashes on unexpected access.

Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/lustre/lustre/libcfs/module.c

index d5a047bd0180cd2123b14431b598274294382326..611607ab92dbceaf68ec8b35187c39cd221c6994 100644 (file)
@@ -502,13 +502,36 @@ static ssize_t lnet_debugfs_write(struct file *filp, const char __user *buf,
        return error;
 }
 
-static const struct file_operations lnet_debugfs_file_operations = {
+static const struct file_operations lnet_debugfs_file_operations_rw = {
        .open           = simple_open,
        .read           = lnet_debugfs_read,
        .write          = lnet_debugfs_write,
        .llseek         = default_llseek,
 };
 
+static const struct file_operations lnet_debugfs_file_operations_ro = {
+       .open           = simple_open,
+       .read           = lnet_debugfs_read,
+       .llseek         = default_llseek,
+};
+
+static const struct file_operations lnet_debugfs_file_operations_wo = {
+       .open           = simple_open,
+       .write          = lnet_debugfs_write,
+       .llseek         = default_llseek,
+};
+
+static const struct file_operations *lnet_debugfs_fops_select(umode_t mode)
+{
+       if (!(mode & S_IWUGO))
+               return &lnet_debugfs_file_operations_ro;
+
+       if (!(mode & S_IRUGO))
+               return &lnet_debugfs_file_operations_wo;
+
+       return &lnet_debugfs_file_operations_rw;
+}
+
 void lustre_insert_debugfs(struct ctl_table *table,
                           const struct lnet_debugfs_symlink_def *symlinks)
 {
@@ -525,7 +548,7 @@ void lustre_insert_debugfs(struct ctl_table *table,
        for (; table->procname; table++)
                debugfs_create_file(table->procname, table->mode,
                                    lnet_debugfs_root, table,
-                                   &lnet_debugfs_file_operations);
+                                   lnet_debugfs_fops_select(table->mode));
 
        for (; symlinks && symlinks->name; symlinks++)
                debugfs_create_symlink(symlinks->name, lnet_debugfs_root,