From 08e6d76821557da7c443dc56ea430c7c92b36a6f Mon Sep 17 00:00:00 2001 From: zhangliguang Date: Thu, 27 Dec 2018 16:31:26 +0800 Subject: [PATCH] alinux: fs,ext4: remove projid limit when create hard link This is a temporary workaround plan to avoid the limitation when creating hard link cross two projids. Signed-off-by: zhangliguang Reviewed-by: Liu Bo Signed-off-by: Joseph Qi Acked-by: Caspar Zhang --- Documentation/sysctl/fs.txt | 10 ++++++++++ fs/ext4/namei.c | 3 ++- include/linux/fs.h | 1 + kernel/sys.c | 3 +++ kernel/sysctl.c | 9 +++++++++ 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt index 819caf8ca05f..15ec58f0dd31 100644 --- a/Documentation/sysctl/fs.txt +++ b/Documentation/sysctl/fs.txt @@ -36,6 +36,7 @@ Currently, these files are in /proc/sys/fs: - pipe-user-pages-soft - protected_fifos - protected_hardlinks +- hardlink_cross_projid - protected_regular - protected_symlinks - suid_dumpable @@ -238,6 +239,15 @@ When set to "2" it also applies to group writable sticky directories. ============================================================== +hardlink_cross_projid: + +This is a temporary workaround plan to avoid the limitation when creating +hard link cross two projids. When set to "0", hardlink creation cross +two projids is restricted. When set to "1" hardlinks can be created +cross two projids. + +============================================================== + protected_symlinks: A long-standing class of security issues is the symlink-based diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index f56d6f1950b9..62f57fcb8e8b 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3224,7 +3224,8 @@ static int ext4_link(struct dentry *old_dentry, if (err) return err; - if ((ext4_test_inode_flag(dir, EXT4_INODE_PROJINHERIT)) && + if (!sysctl_hardlink_cross_projid && + (ext4_test_inode_flag(dir, EXT4_INODE_PROJINHERIT)) && (!projid_eq(EXT4_I(dir)->i_projid, EXT4_I(old_dentry->d_inode)->i_projid))) return -EXDEV; diff --git a/include/linux/fs.h b/include/linux/fs.h index 92420009b9bc..71827fc026f0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -74,6 +74,7 @@ extern struct inodes_stat_t inodes_stat; extern int leases_enable, lease_break_time; extern int sysctl_protected_symlinks; extern int sysctl_protected_hardlinks; +extern int sysctl_hardlink_cross_projid; extern int sysctl_protected_fifos; extern int sysctl_protected_regular; diff --git a/kernel/sys.c b/kernel/sys.c index 096932a45046..6f7a0c9e83f3 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -144,6 +144,9 @@ int fs_overflowgid = DEFAULT_FS_OVERFLOWGID; EXPORT_SYMBOL(fs_overflowuid); EXPORT_SYMBOL(fs_overflowgid); +int sysctl_hardlink_cross_projid = 0; +EXPORT_SYMBOL(sysctl_hardlink_cross_projid); + /* * Returns true if current's euid is same as p's uid or euid, * or has CAP_SYS_NICE to p's user_ns. diff --git a/kernel/sysctl.c b/kernel/sysctl.c index b7fd05287475..8a5f85651ba6 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1874,6 +1874,15 @@ static struct ctl_table fs_table[] = { .proc_handler = proc_dointvec_minmax, .extra1 = &one, }, + { + .procname = "hardlink_cross_projid", + .data = &sysctl_hardlink_cross_projid, + .maxlen = sizeof(int), + .mode = 0600, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, + }, { } }; -- GitLab