Skip to content

Commit 69c433e

Browse files
author
Miklos Szeredi
committed
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>
1 parent 7c37fbd commit 69c433e

File tree

3 files changed

+27
-0
lines changed

3 files changed

+27
-0
lines changed

Diff for: fs/ecryptfs/main.c

+7
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,13 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
566566
s->s_maxbytes = path.dentry->d_sb->s_maxbytes;
567567
s->s_blocksize = path.dentry->d_sb->s_blocksize;
568568
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+
}
569576

570577
inode = ecryptfs_get_inode(path.dentry->d_inode, s);
571578
rc = PTR_ERR(inode);

Diff for: fs/overlayfs/super.c

+9
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,15 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
677677
}
678678
ufs->lower_namelen = statfs.f_namelen;
679679

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+
680689
ufs->upper_mnt = clone_private_mount(&upperpath);
681690
err = PTR_ERR(ufs->upper_mnt);
682691
if (IS_ERR(ufs->upper_mnt)) {

Diff for: include/linux/fs.h

+11
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,12 @@ struct iattr {
261261
*/
262262
#include <linux/quota.h>
263263

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+
264270
/**
265271
* enum positive_aop_returns - aop return codes with specific semantics
266272
*
@@ -1273,6 +1279,11 @@ struct super_block {
12731279
struct list_lru s_dentry_lru ____cacheline_aligned_in_smp;
12741280
struct list_lru s_inode_lru ____cacheline_aligned_in_smp;
12751281
struct rcu_head rcu;
1282+
1283+
/*
1284+
* Indicates how deep in a filesystem stack this SB is
1285+
*/
1286+
int s_stack_depth;
12761287
};
12771288

12781289
extern struct timespec current_fs_time(struct super_block *sb);

0 commit comments

Comments
 (0)