aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2014-10-23 18:14:39 -0400
committerMiklos Szeredi <mszeredi@suse.cz>2014-10-23 18:14:39 -0400
commit69c433ed2ecd2d3264efd7afec4439524b319121 (patch)
tree49fcf55fbd3913881ccb47a6e700f668a4307daf
parent7c37fbda85ceb9be7bdb9d5f53e702efc40cf783 (diff)
fs: limit filesystem stacking depth
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. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
-rw-r--r--fs/ecryptfs/main.c7
-rw-r--r--fs/overlayfs/super.c9
-rw-r--r--include/linux/fs.h11
3 files changed, 27 insertions, 0 deletions
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 1b119d3bf924..c4cd1fd86cc2 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -566,6 +566,13 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
566 s->s_maxbytes = path.dentry->d_sb->s_maxbytes; 566 s->s_maxbytes = path.dentry->d_sb->s_maxbytes;
567 s->s_blocksize = path.dentry->d_sb->s_blocksize; 567 s->s_blocksize = path.dentry->d_sb->s_blocksize;
568 s->s_magic = ECRYPTFS_SUPER_MAGIC; 568 s->s_magic = ECRYPTFS_SUPER_MAGIC;
569 s->s_stack_depth = path.dentry->d_sb->s_stack_depth + 1;
570
571 rc = -EINVAL;
572 if (s->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
573 pr_err("eCryptfs: maximum fs stacking depth exceeded\n");
574 goto out_free;
575 }
569 576
570 inode = ecryptfs_get_inode(path.dentry->d_inode, s); 577 inode = ecryptfs_get_inode(path.dentry->d_inode, s);
571 rc = PTR_ERR(inode); 578 rc = PTR_ERR(inode);
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 7dcc24e84417..08b704cebfc4 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -677,6 +677,15 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
677 } 677 }
678 ufs->lower_namelen = statfs.f_namelen; 678 ufs->lower_namelen = statfs.f_namelen;
679 679
680 sb->s_stack_depth = max(upperpath.mnt->mnt_sb->s_stack_depth,
681 lowerpath.mnt->mnt_sb->s_stack_depth) + 1;
682
683 err = -EINVAL;
684 if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
685 pr_err("overlayfs: maximum fs stacking depth exceeded\n");
686 goto out_put_workpath;
687 }
688
680 ufs->upper_mnt = clone_private_mount(&upperpath); 689 ufs->upper_mnt = clone_private_mount(&upperpath);
681 err = PTR_ERR(ufs->upper_mnt); 690 err = PTR_ERR(ufs->upper_mnt);
682 if (IS_ERR(ufs->upper_mnt)) { 691 if (IS_ERR(ufs->upper_mnt)) {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 69118b3cb917..4e41a4a331bb 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -261,6 +261,12 @@ struct iattr {
261 */ 261 */
262#include <linux/quota.h> 262#include <linux/quota.h>
263 263
264/*
265 * Maximum number of layers of fs stack. Needs to be limited to
266 * prevent kernel stack overflow
267 */
268#define FILESYSTEM_MAX_STACK_DEPTH 2
269
264/** 270/**
265 * enum positive_aop_returns - aop return codes with specific semantics 271 * enum positive_aop_returns - aop return codes with specific semantics
266 * 272 *
@@ -1273,6 +1279,11 @@ struct super_block {
1273 struct list_lru s_dentry_lru ____cacheline_aligned_in_smp; 1279 struct list_lru s_dentry_lru ____cacheline_aligned_in_smp;
1274 struct list_lru s_inode_lru ____cacheline_aligned_in_smp; 1280 struct list_lru s_inode_lru ____cacheline_aligned_in_smp;
1275 struct rcu_head rcu; 1281 struct rcu_head rcu;
1282
1283 /*
1284 * Indicates how deep in a filesystem stack this SB is
1285 */
1286 int s_stack_depth;
1276}; 1287};
1277 1288
1278extern struct timespec current_fs_time(struct super_block *sb); 1289extern struct timespec current_fs_time(struct super_block *sb);