mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
93 lines
2.9 KiB
Diff
93 lines
2.9 KiB
Diff
From 69c433ed2ecd2d3264efd7afec4439524b319121 Mon Sep 17 00:00:00 2001
|
|
From: Miklos Szeredi <mszeredi@suse.cz>
|
|
Date: Fri, 24 Oct 2014 00:14:39 +0200
|
|
Subject: 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>
|
|
---
|
|
fs/ecryptfs/main.c | 7 +++++++
|
|
fs/overlayfs/super.c | 9 +++++++++
|
|
include/linux/fs.h | 11 +++++++++++
|
|
3 files changed, 27 insertions(+)
|
|
|
|
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
|
|
index 1b119d3..c4cd1fd 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
|
|
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);
|
|
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
|
|
index 7dcc24e..08b704c 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)
|
|
}
|
|
ufs->lower_namelen = statfs.f_namelen;
|
|
|
|
+ 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) {
|
|
+ pr_err("overlayfs: maximum fs stacking depth exceeded\n");
|
|
+ goto out_put_workpath;
|
|
+ }
|
|
+
|
|
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 69118b3..4e41a4a 100644
|
|
--- a/include/linux/fs.h
|
|
+++ b/include/linux/fs.h
|
|
@@ -261,6 +261,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
|
|
*
|
|
@@ -1273,6 +1279,11 @@ struct super_block {
|
|
struct list_lru s_dentry_lru ____cacheline_aligned_in_smp;
|
|
struct list_lru s_inode_lru ____cacheline_aligned_in_smp;
|
|
struct rcu_head rcu;
|
|
+
|
|
+ /*
|
|
+ * Indicates how deep in a filesystem stack this SB is
|
|
+ */
|
|
+ int s_stack_depth;
|
|
};
|
|
|
|
extern struct timespec current_fs_time(struct super_block *sb);
|
|
--
|
|
cgit v1.1
|
|
|