FAILED: patch "[PATCH] ext4: don't allow any modifications to an immutable file" failed to apply to 4.9-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2e53840362771c73eb0a5ff71611507e64e8eecd Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <[email protected]>
Date: Sun, 9 Jun 2019 21:41:41 -0400
Subject: [PATCH] ext4: don't allow any modifications to an immutable file
Don't allow any modifications to a file that's marked immutable, which means that we have to flush all the writable pages to make the readonly and we have to check the setattr/setflags parameters more closely.
Signed-off-by Darrick J. Wong <[email protected]>
Signed-off-by Theodore Ts'o <[email protected]>
fs/ext4/ioctl.c +45 -1
@@ -269,6 +269,29 @@ static int uuid_is_zero(__u8 u[16]) }#endif +/* +* If immutable is set and we are not clearing it, we're not allowed to change +* anything else in the inode. Don't error out if we're only trying to set +* immutable on an immutable file. +*/ +static int ext4_ioctl_check_immutable (struct inode *inode,__u32 new_projid, +unsigned int flags) +{ +struct ext4_inode_info *ei =EXT4_I (inode); +unsigned int oldflags = ei->i_flags; + +if (!(oldflags &EXT4_IMMUTABLE_FL ) || !(flags &EXT4_IMMUTABLE_FL )) +return 0 ; + +if ((oldflags & ~EXT4_IMMUTABLE_FL ) != (flags & ~EXT4_IMMUTABLE_FL )) +return -EPERM ; +if (ext4_has_feature_project (inode->i_sb) && +__kprojid_val (ei->i_projid) != new_projid) +return -EPERM ; + +return 0 ; +} +static int ext4_ioctl_setflags (struct inode *inode,unsigned int flags) {
@@ -340,6 +363,20 @@ static int ext4_ioctl_setflags(struct inode *inode, } } +/* +* Wait for all pending directio and then flush all the dirty pages +* for this file. The flush marks all the pages readonly, so any +* subsequent attempt to write to the file (particularly mmap pages) +* will come through the filesystem and fail. +*/ +if (S_ISREG (inode->i_mode) && !IS_IMMUTABLE (inode) && + (flags &EXT4_IMMUTABLE_FL )) { +inode_dio_wait (inode); + err =filemap_write_and_wait (inode->i_mapping); +if (err) + goto flags_out; + } + handle =ext4_journal_start (inode,EXT4_HT_INODE ,1 );if (IS_ERR (handle)) { err =PTR_ERR (handle);
@@ -769,7 +806,11 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)return err;inode_lock (inode); - err =ext4_ioctl_setflags (inode, flags); + err =ext4_ioctl_check_immutable (inode, +from_kprojid (&init_user_ns, ei->i_projid), + flags); +if (!err) + err =ext4_ioctl_setflags (inode, flags);inode_unlock (inode);mnt_drop_write_file (filp);return err;
@@ -1139,6 +1180,9 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto out; flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE ) | (flags &EXT4_FL_XFLAG_VISIBLE ); + err =ext4_ioctl_check_immutable (inode, fa.fsx_projid, flags); +if (err) + goto out; err =ext4_ioctl_setflags (inode, flags);if (err) goto out;