Re: [PATCH 08/13] fs: limit filesystem stacking depth

Sedat Dilek
2012-08-16T08:02:20Z

[-- Attachment #1: Type: text/plain, Size: 4316 bytes --]

On Wed, Aug 15, 2012 at 5:48 PM, Miklos Szeredi <miklos@szeredi.hu> wrote:
> From: Miklos Szeredi <mszeredi@suse.cz>
>
> Add a simple read-only counter to super_block that indicates 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.
>

Hi,

I have tested OverlayFS for a long time with "fs-stack-depth=3".
The original OverlayFS test-case script from Jordi was slightly
modified (see "testcase-ovl-v3.sh").
I have sent my test-results to Andy and Jordi (tested with the
patchset from Andy against Linux-v3.4 [1] with Ext4-FS).
The attached test-case script *requires* "fs-stack-depth=3" to run
properly (patch attached).

So, I have 2 questions:

[1] FS-stack-limitation

Is a "fs-stack-depth>=2" (like "3") critical?
Is your setting to "2" just a defensive (and initial) one?
Can you explain your choice a bit more as ecryptFS is involved in this
limitation, too.

[2] Test-Case/Use-Case scripts

It would be *very very very* helpful if you could provide or even ship
in the Linux-kernel a test-case/use-case script, Thanks!
Maybe describe "Documentation/filesystems/overlayfs.txt" would be a good place?
Helpful could be a "simple" and a "complex" testing scenario?

- Sedat -

[1] http://git.kernel.org/?p=linux/kernel/git/apw/overlayfs.git;a=shortlog;h=refs/heads/overlayfs.v12apw1

> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
> ---
> fs/ecryptfs/main.c | 7 +++++++
> fs/overlayfs/super.c | 10 ++++++++++
> include/linux/fs.h | 11 +++++++++++
> 3 files changed, 28 insertions(+), 0 deletions(-)
>
> diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
> index 2768138..344fb2c 100644
> --- a/fs/ecryptfs/main.c
> +++ b/fs/ecryptfs/main.c
> @@ -565,6 +565,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) {
> + printk(KERN_ERR "eCryptfs: maximum fs stacking depth exceeded\n");
> + goto out_free;
> + }
>
> inode = ecryptfs_get_inode(path.dentry->d_inode, s);
> rc = PTR_ERR(inode);
> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
> index 69a2099..64d2695 100644
> --- a/fs/overlayfs/super.c
> +++ b/fs/overlayfs/super.c
> @@ -551,6 +551,16 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
> !S_ISDIR(lowerpath.dentry->d_inode->i_mode))
> goto out_put_lowerpath;
>
> + sb->s_stack_depth = max(upperpath.mnt->mnt_sb->s_stack_depth,
> + lowerpath.mnt->mnt_sb->s_stack_depth) + 1;
> +
> + err = -EINVAL;
> + if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
> + printk(KERN_ERR "overlayfs: maximum fs stacking depth exceeded\n");
> + goto out_put_lowerpath;
> + }
> +
> +
> ufs->upper_mnt = clone_private_mount(&upperpath);
> err = PTR_ERR(ufs->upper_mnt);
> if (IS_ERR(ufs->upper_mnt)) {
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index abc7a53..1265e24 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -505,6 +505,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
> *
> @@ -1579,6 +1585,11 @@ struct super_block {
>
> /* Being remounted read-only */
> int s_readonly_remount;
> +
> + /*
> + * Indicates how deep in a filesystem stack this SB is
> + */
> + int s_stack_depth;
> };
>
> /* superblock cache pruning functions */
> --
> 1.7.7
>

[-- Attachment #2: testcase-ovl-v3.sh --]
[-- Type: application/x-sh, Size: 4801 bytes --]

[-- Attachment #3: 0001-fs-Increase-limit-filesystem-stacking-depth-to-3.patch --]
[-- Type: application/octet-stream, Size: 796 bytes --]

From 48e8d478c7afb3fcd9f75b310adda15b48258a54 Mon Sep 17 00:00:00 2001
From: Sedat Dilek <sedat.dilek@gmail.com>
Date: Sat, 28 Apr 2012 17:11:16 +0200
Subject: [PATCH] fs: Increase limit filesystem stacking depth to 3

Signed-off-by: Sedat Dilek <sedat.dilek@gmail.com>
---
include/linux/fs.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index fdd1d38..ad333e5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -493,7 +493,7 @@ struct iattr {
* Maximum number of layers of fs stack. Needs to be limited to
* prevent kernel stack overflow
*/
-#define FILESYSTEM_MAX_STACK_DEPTH 2
+#define FILESYSTEM_MAX_STACK_DEPTH 3

/**
* enum positive_aop_returns - aop return codes with specific semantics
--
1.7.9.5