fs: limit filesystem stacking depth
Miklos Szeredi [Thu, 23 Oct 2014 22:14:39 +0000 (00:14 +0200)]
Add a simple read-only counter to super_block that indicates how deep this
is in the stack of filesystems.  Previously ecryptfs was the only stackable
filesystem and it explicitly disallowed multiple layers of itself.

Overlayfs, however, can be stacked recursively and also may be stacked
on top of ecryptfs or vice versa.

To limit the kernel stack usage we must limit the depth of the
filesystem stack.  Initially the limit is set to 2.

Bug 1887273
Bug 200288656

Change-Id: Ibaa154eb2b102d02370fe2003387b0131fe2955a
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Gagan Grover <ggrover@nvidia.com>
Reviewed-on: http://git-master/r/1455849
(cherry picked from commit 5fa62435eaef75e479c0c157b4d911344f64b002)
Reviewed-on: http://git-master/r/1459845
(cherry picked from commit f9aa5494d35892be63c7268deb7fe7adacb6123e)
Reviewed-on: http://git-master/r/1463477
GVS: Gerrit_Virtual_Submit
Reviewed-by: Manish Tuteja <mtuteja@nvidia.com>

fs/ecryptfs/main.c
include/linux/fs.h

index 329a9cc..8a041bb 100644 (file)
@@ -577,6 +577,13 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
        s->s_maxbytes = path.dentry->d_sb->s_maxbytes;
        s->s_blocksize = path.dentry->d_sb->s_blocksize;
        s->s_magic = ECRYPTFS_SUPER_MAGIC;
+       s->s_stack_depth = path.dentry->d_sb->s_stack_depth + 1;
+
+       rc = -EINVAL;
+       if (s->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
+               pr_err("eCryptfs: maximum fs stacking depth exceeded\n");
+               goto out_free;
+       }
 
        inode = ecryptfs_get_inode(path.dentry->d_inode, s);
        rc = PTR_ERR(inode);
index f169cb5..8a144c6 100644 (file)
@@ -245,6 +245,12 @@ struct iattr {
  */
 #include <linux/quota.h>
 
+/*
+ * Maximum number of layers of fs stack.  Needs to be limited to
+ * prevent kernel stack overflow
+ */
+#define FILESYSTEM_MAX_STACK_DEPTH 2
+
 /** 
  * enum positive_aop_returns - aop return codes with specific semantics
  *
@@ -1319,6 +1325,11 @@ struct super_block {
 
        /* AIO completions deferred from interrupt context */
        struct workqueue_struct *s_dio_done_wq;
+
+       /*
+        * Indicates how deep in a filesystem stack this SB is
+        */
+       int s_stack_depth;
 };
 
 /* superblock cache pruning functions */