summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2017-10-08 14:48:44 +0100
committerBen Hutchings <ben@decadent.org.uk>2017-10-12 15:27:18 +0100
commit4a79ebbdd0231a4afcd758314b3852501694e44f (patch)
treef10b352f37afa98d63f1ad0a9796ee07d9e5d6b9 /fs
parent6b49d3b542cc262009a4d3f878bc003d59b2c304 (diff)
ext3: preserve i_mode if ext2_set_acl() fails
Based on Ernesto A. Fernández's fix for ext2 (commit fe26569eb919), from which the following description is taken: > When changing a file's acl mask, ext2_set_acl() will first set the group > bits of i_mode to the value of the mask, and only then set the actual > extended attribute representing the new acl. > > If the second part fails (due to lack of space, for example) and the file > had no acl attribute to begin with, the system will from now on assume > that the mask permission bits are actual group permission bits, potentially > granting access to the wrong users. > > Prevent this by only changing the inode mode after the acl has been set. Cc: Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com> Cc: Jan Kara <jack@suse.cz> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/ext3/acl.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index 0a6db91b556e..c84a8f6ce4c3 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -231,15 +231,22 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
struct posix_acl *acl)
{
int error;
+ int update_mode = 0;
+ umode_t mode = inode->i_mode;
if (type == ACL_TYPE_ACCESS && acl) {
- error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ error = posix_acl_update_mode(inode, &mode, &acl);
if (error)
return error;
+ update_mode = 1;
+ }
+ error = __ext3_set_acl(handle, inode, type, acl);
+ if (!error && update_mode) {
+ inode->i_mode = mode;
inode->i_ctime = CURRENT_TIME_SEC;
ext3_mark_inode_dirty(handle, inode);
}
- return __ext3_set_acl(handle, inode, type, acl);
+ return error;
}
/*