2017-11-25 19:39:02 -05:00
|
|
|
From 6b0c893dc08060d6999b07136391d8a298678dae Mon Sep 17 00:00:00 2001
|
2017-10-29 01:48:53 -04:00
|
|
|
From: Jan Kara <jack@suse.cz>
|
|
|
|
Date: Mon, 19 Sep 2016 17:39:09 +0200
|
2017-11-25 19:39:02 -05:00
|
|
|
Subject: [PATCH] BACKPORT: posix_acl: Clear SGID bit when setting file
|
|
|
|
permissions
|
|
|
|
|
|
|
|
(cherry pick from commit 073931017b49d9458aa351605b43a7e34598caef)
|
2017-10-29 01:48:53 -04:00
|
|
|
|
|
|
|
When file permissions are modified via chmod(2) and the user is not in
|
|
|
|
the owning group or capable of CAP_FSETID, the setgid bit is cleared in
|
|
|
|
inode_change_ok(). Setting a POSIX ACL via setxattr(2) sets the file
|
|
|
|
permissions as well as the new ACL, but doesn't clear the setgid bit in
|
|
|
|
a similar way; this allows to bypass the check in chmod(2). Fix that.
|
|
|
|
|
2017-11-25 19:39:02 -05:00
|
|
|
NB: conflicts resolution included extending the change to all visible
|
|
|
|
users of the near deprecated function posix_acl_equiv_mode
|
|
|
|
replaced with posix_acl_update_mode. We did not resolve the ACL
|
|
|
|
leak in this CL, require additional upstream fixes.
|
|
|
|
|
2017-10-29 01:48:53 -04:00
|
|
|
References: CVE-2016-7097
|
|
|
|
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
|
|
|
Reviewed-by: Jeff Layton <jlayton@redhat.com>
|
|
|
|
Signed-off-by: Jan Kara <jack@suse.cz>
|
|
|
|
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
|
2017-11-25 19:39:02 -05:00
|
|
|
Bug: 32458736
|
|
|
|
Change-Id: I19591ad452cc825ac282b3cfd2daaa72aa9a1ac1
|
2017-10-29 01:48:53 -04:00
|
|
|
---
|
|
|
|
fs/9p/acl.c | 40 +++++++++++++++++-----------------------
|
|
|
|
fs/btrfs/acl.c | 6 ++----
|
|
|
|
fs/ext2/acl.c | 12 ++++--------
|
2017-11-25 19:39:02 -05:00
|
|
|
fs/ext3/acl.c | 12 ++++--------
|
2017-10-29 01:48:53 -04:00
|
|
|
fs/ext4/acl.c | 12 ++++--------
|
|
|
|
fs/f2fs/acl.c | 6 ++----
|
2017-11-25 19:39:02 -05:00
|
|
|
fs/generic_acl.c | 8 ++------
|
|
|
|
fs/gfs2/acl.c | 11 +++--------
|
2017-10-29 01:48:53 -04:00
|
|
|
fs/jffs2/acl.c | 9 ++++-----
|
2017-11-25 19:39:02 -05:00
|
|
|
fs/jfs/xattr.c | 6 +++---
|
|
|
|
fs/ocfs2/acl.c | 18 ++++++------------
|
2017-10-29 01:48:53 -04:00
|
|
|
fs/posix_acl.c | 31 +++++++++++++++++++++++++++++++
|
|
|
|
fs/reiserfs/xattr_acl.c | 8 ++------
|
2017-11-25 19:39:02 -05:00
|
|
|
fs/xfs/xfs_acl.c | 13 +++----------
|
2017-10-29 01:48:53 -04:00
|
|
|
include/linux/posix_acl.h | 1 +
|
2017-11-25 19:39:02 -05:00
|
|
|
15 files changed, 88 insertions(+), 105 deletions(-)
|
2017-10-29 01:48:53 -04:00
|
|
|
|
|
|
|
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
index 7af425f53beef..9686c1f17653f 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/9p/acl.c
|
|
|
|
+++ b/fs/9p/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -320,32 +320,26 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
|
2017-10-29 01:48:53 -04:00
|
|
|
case ACL_TYPE_ACCESS:
|
2017-11-25 19:39:02 -05:00
|
|
|
name = POSIX_ACL_XATTR_ACCESS;
|
2017-10-29 01:48:53 -04:00
|
|
|
if (acl) {
|
|
|
|
- umode_t mode = inode->i_mode;
|
|
|
|
- retval = posix_acl_equiv_mode(acl, &mode);
|
|
|
|
- if (retval < 0)
|
|
|
|
+ struct iattr iattr;
|
|
|
|
+
|
|
|
|
+ retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
|
|
|
|
+ if (retval)
|
|
|
|
goto err_out;
|
|
|
|
- else {
|
|
|
|
- struct iattr iattr;
|
|
|
|
- if (retval == 0) {
|
|
|
|
- /*
|
|
|
|
- * ACL can be represented
|
|
|
|
- * by the mode bits. So don't
|
|
|
|
- * update ACL.
|
|
|
|
- */
|
|
|
|
- acl = NULL;
|
|
|
|
- value = NULL;
|
|
|
|
- size = 0;
|
|
|
|
- }
|
|
|
|
- /* Updte the mode bits */
|
|
|
|
- iattr.ia_mode = ((mode & S_IALLUGO) |
|
|
|
|
- (inode->i_mode & ~S_IALLUGO));
|
|
|
|
- iattr.ia_valid = ATTR_MODE;
|
|
|
|
- /* FIXME should we update ctime ?
|
|
|
|
- * What is the following setxattr update the
|
|
|
|
- * mode ?
|
|
|
|
+ if (!acl) {
|
|
|
|
+ /*
|
|
|
|
+ * ACL can be represented
|
|
|
|
+ * by the mode bits. So don't
|
|
|
|
+ * update ACL.
|
|
|
|
*/
|
|
|
|
- v9fs_vfs_setattr_dotl(dentry, &iattr);
|
|
|
|
+ value = NULL;
|
|
|
|
+ size = 0;
|
|
|
|
}
|
|
|
|
+ iattr.ia_valid = ATTR_MODE;
|
|
|
|
+ /* FIXME should we update ctime ?
|
|
|
|
+ * What is the following setxattr update the
|
|
|
|
+ * mode ?
|
|
|
|
+ */
|
|
|
|
+ v9fs_vfs_setattr_dotl(dentry, &iattr);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ACL_TYPE_DEFAULT:
|
|
|
|
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
index 0890c83643e94..d6d53e5e7945d 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/btrfs/acl.c
|
|
|
|
+++ b/fs/btrfs/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -118,11 +118,9 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans,
|
2017-10-29 01:48:53 -04:00
|
|
|
case ACL_TYPE_ACCESS:
|
2017-11-25 19:39:02 -05:00
|
|
|
name = POSIX_ACL_XATTR_ACCESS;
|
2017-10-29 01:48:53 -04:00
|
|
|
if (acl) {
|
|
|
|
- ret = posix_acl_equiv_mode(acl, &inode->i_mode);
|
|
|
|
- if (ret < 0)
|
|
|
|
+ ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
|
|
|
+ if (ret)
|
|
|
|
return ret;
|
|
|
|
- if (ret == 0)
|
|
|
|
- acl = NULL;
|
|
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
index 110b6b371a4ed..48c3c2d7d2619 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/ext2/acl.c
|
|
|
|
+++ b/fs/ext2/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -206,15 +206,11 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
|
2017-10-29 01:48:53 -04:00
|
|
|
case ACL_TYPE_ACCESS:
|
|
|
|
name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
|
|
|
|
if (acl) {
|
|
|
|
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
|
|
|
|
- if (error < 0)
|
|
|
|
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
|
|
|
+ if (error)
|
|
|
|
return error;
|
|
|
|
- else {
|
|
|
|
- inode->i_ctime = CURRENT_TIME_SEC;
|
|
|
|
- mark_inode_dirty(inode);
|
|
|
|
- if (error == 0)
|
|
|
|
- acl = NULL;
|
|
|
|
- }
|
|
|
|
+ inode->i_ctime = CURRENT_TIME_SEC;
|
|
|
|
+ mark_inode_dirty(inode);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2017-11-25 19:39:02 -05:00
|
|
|
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
|
|
|
|
index dbb5ad59a7fc3..bb2f60a62d82a 100644
|
|
|
|
--- a/fs/ext3/acl.c
|
|
|
|
+++ b/fs/ext3/acl.c
|
|
|
|
@@ -205,15 +205,11 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
|
|
|
|
case ACL_TYPE_ACCESS:
|
|
|
|
name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
|
|
|
|
if (acl) {
|
|
|
|
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
|
|
|
|
- if (error < 0)
|
|
|
|
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
|
|
|
+ if (error)
|
|
|
|
return error;
|
|
|
|
- else {
|
|
|
|
- inode->i_ctime = CURRENT_TIME_SEC;
|
|
|
|
- ext3_mark_inode_dirty(handle, inode);
|
|
|
|
- if (error == 0)
|
|
|
|
- acl = NULL;
|
|
|
|
- }
|
|
|
|
+ inode->i_ctime = CURRENT_TIME_SEC;
|
|
|
|
+ ext3_mark_inode_dirty(handle, inode);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2017-10-29 01:48:53 -04:00
|
|
|
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
index d40c8dbbb0d66..87d9bbf6a53f3 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/ext4/acl.c
|
|
|
|
+++ b/fs/ext4/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -201,15 +201,11 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type,
|
2017-10-29 01:48:53 -04:00
|
|
|
case ACL_TYPE_ACCESS:
|
|
|
|
name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
|
|
|
|
if (acl) {
|
|
|
|
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
|
|
|
|
- if (error < 0)
|
|
|
|
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
|
|
|
+ if (error)
|
|
|
|
return error;
|
|
|
|
- else {
|
|
|
|
- inode->i_ctime = ext4_current_time(inode);
|
|
|
|
- ext4_mark_inode_dirty(handle, inode);
|
|
|
|
- if (error == 0)
|
|
|
|
- acl = NULL;
|
|
|
|
- }
|
|
|
|
+ inode->i_ctime = ext4_current_time(inode);
|
|
|
|
+ ext4_mark_inode_dirty(handle, inode);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
index 44abc2f286e00..9c4f3c732bce4 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/f2fs/acl.c
|
|
|
|
+++ b/fs/f2fs/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -223,12 +223,10 @@ static int f2fs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
|
2017-10-29 01:48:53 -04:00
|
|
|
case ACL_TYPE_ACCESS:
|
|
|
|
name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
|
|
|
|
if (acl) {
|
|
|
|
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
|
|
|
|
- if (error < 0)
|
|
|
|
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
|
|
|
+ if (error)
|
|
|
|
return error;
|
2017-11-25 19:39:02 -05:00
|
|
|
set_acl_inode(fi, inode->i_mode);
|
2017-10-29 01:48:53 -04:00
|
|
|
- if (error == 0)
|
|
|
|
- acl = NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2017-11-25 19:39:02 -05:00
|
|
|
diff --git a/fs/generic_acl.c b/fs/generic_acl.c
|
|
|
|
index b3f3676796d31..21408084c3b34 100644
|
|
|
|
--- a/fs/generic_acl.c
|
|
|
|
+++ b/fs/generic_acl.c
|
|
|
|
@@ -87,14 +87,10 @@ generic_acl_set(struct dentry *dentry, const char *name, const void *value,
|
|
|
|
goto failed;
|
|
|
|
switch (type) {
|
|
|
|
case ACL_TYPE_ACCESS:
|
|
|
|
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
|
|
|
|
- if (error < 0)
|
|
|
|
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
|
|
|
+ if (error)
|
|
|
|
goto failed;
|
|
|
|
inode->i_ctime = CURRENT_TIME;
|
|
|
|
- if (error == 0) {
|
|
|
|
- posix_acl_release(acl);
|
|
|
|
- acl = NULL;
|
|
|
|
- }
|
|
|
|
break;
|
|
|
|
case ACL_TYPE_DEFAULT:
|
|
|
|
if (!S_ISDIR(inode->i_mode)) {
|
2017-10-29 01:48:53 -04:00
|
|
|
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
index f69ac0af5496c..e7b330ef4dfda 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/gfs2/acl.c
|
|
|
|
+++ b/fs/gfs2/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -268,15 +268,10 @@ static int gfs2_xattr_system_set(struct dentry *dentry, const char *name,
|
|
|
|
|
2017-10-29 01:48:53 -04:00
|
|
|
if (type == ACL_TYPE_ACCESS) {
|
|
|
|
umode_t mode = inode->i_mode;
|
|
|
|
- error = posix_acl_equiv_mode(acl, &mode);
|
|
|
|
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
2017-11-25 19:39:02 -05:00
|
|
|
|
|
|
|
- if (error <= 0) {
|
|
|
|
- posix_acl_release(acl);
|
2017-10-29 01:48:53 -04:00
|
|
|
- acl = NULL;
|
|
|
|
-
|
2017-11-25 19:39:02 -05:00
|
|
|
- if (error < 0)
|
|
|
|
- return error;
|
2017-10-29 01:48:53 -04:00
|
|
|
- }
|
2017-11-25 19:39:02 -05:00
|
|
|
+ if (error)
|
|
|
|
+ goto out_release;
|
2017-10-29 01:48:53 -04:00
|
|
|
|
2017-11-25 19:39:02 -05:00
|
|
|
error = gfs2_set_mode(inode, mode);
|
|
|
|
if (error)
|
2017-10-29 01:48:53 -04:00
|
|
|
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
index 223283c301116..9335b8d3cf521 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/jffs2/acl.c
|
|
|
|
+++ b/fs/jffs2/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -243,9 +243,10 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
|
2017-10-29 01:48:53 -04:00
|
|
|
case ACL_TYPE_ACCESS:
|
|
|
|
xprefix = JFFS2_XPREFIX_ACL_ACCESS;
|
|
|
|
if (acl) {
|
|
|
|
- umode_t mode = inode->i_mode;
|
|
|
|
- rc = posix_acl_equiv_mode(acl, &mode);
|
|
|
|
- if (rc < 0)
|
|
|
|
+ umode_t mode;
|
|
|
|
+
|
|
|
|
+ rc = posix_acl_update_mode(inode, &mode, &acl);
|
|
|
|
+ if (rc)
|
|
|
|
return rc;
|
|
|
|
if (inode->i_mode != mode) {
|
|
|
|
struct iattr attr;
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -257,8 +258,6 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
|
2017-10-29 01:48:53 -04:00
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
- if (rc == 0)
|
|
|
|
- acl = NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ACL_TYPE_DEFAULT:
|
2017-11-25 19:39:02 -05:00
|
|
|
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
|
|
|
|
index 42d67f9757bf6..c79b1d7a53e24 100644
|
|
|
|
--- a/fs/jfs/xattr.c
|
|
|
|
+++ b/fs/jfs/xattr.c
|
|
|
|
@@ -693,11 +693,11 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
|
|
|
|
return rc;
|
|
|
|
}
|
2017-10-29 01:48:53 -04:00
|
|
|
if (acl) {
|
|
|
|
- rc = posix_acl_equiv_mode(acl, &inode->i_mode);
|
|
|
|
+ rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
2017-11-25 19:39:02 -05:00
|
|
|
posix_acl_release(acl);
|
|
|
|
- if (rc < 0) {
|
|
|
|
+ if (rc) {
|
|
|
|
printk(KERN_ERR
|
|
|
|
- "posix_acl_equiv_mode returned %d\n",
|
|
|
|
+ "posix_acl_update_mode returned %d\n",
|
|
|
|
rc);
|
2017-10-29 01:48:53 -04:00
|
|
|
return rc;
|
2017-11-25 19:39:02 -05:00
|
|
|
}
|
2017-10-29 01:48:53 -04:00
|
|
|
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
index 8a404576fb265..2fe643160cf73 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/ocfs2/acl.c
|
|
|
|
+++ b/fs/ocfs2/acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -275,19 +275,13 @@ static int ocfs2_set_acl(handle_t *handle,
|
2017-10-29 01:48:53 -04:00
|
|
|
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
|
|
|
|
if (acl) {
|
2017-11-25 19:39:02 -05:00
|
|
|
umode_t mode = inode->i_mode;
|
2017-10-29 01:48:53 -04:00
|
|
|
- ret = posix_acl_equiv_mode(acl, &mode);
|
|
|
|
- if (ret < 0)
|
|
|
|
+ ret = posix_acl_update_mode(inode, &mode, &acl);
|
|
|
|
+ if (ret)
|
|
|
|
+ return ret;
|
2017-11-25 19:39:02 -05:00
|
|
|
+ ret = ocfs2_acl_set_mode(inode, di_bh,
|
|
|
|
+ handle, mode);
|
|
|
|
+ if (ret)
|
|
|
|
return ret;
|
|
|
|
- else {
|
|
|
|
- if (ret == 0)
|
|
|
|
- acl = NULL;
|
|
|
|
-
|
|
|
|
- ret = ocfs2_acl_set_mode(inode, di_bh,
|
|
|
|
- handle, mode);
|
|
|
|
- if (ret)
|
|
|
|
- return ret;
|
|
|
|
-
|
|
|
|
- }
|
2017-10-29 01:48:53 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ACL_TYPE_DEFAULT:
|
|
|
|
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
index 3542f1f814e2a..35cc1f40b82df 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/posix_acl.c
|
|
|
|
+++ b/fs/posix_acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -341,6 +341,37 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p)
|
|
|
|
return not_equiv;
|
2017-10-29 01:48:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * posix_acl_update_mode - update mode in set_acl
|
|
|
|
+ *
|
|
|
|
+ * Update the file mode when setting an ACL: compute the new file permission
|
|
|
|
+ * bits based on the ACL. In addition, if the ACL is equivalent to the new
|
|
|
|
+ * file mode, set *acl to NULL to indicate that no ACL should be set.
|
|
|
|
+ *
|
|
|
|
+ * As with chmod, clear the setgit bit if the caller is not in the owning group
|
|
|
|
+ * or capable of CAP_FSETID (see inode_change_ok).
|
|
|
|
+ *
|
|
|
|
+ * Called from set_acl inode operations.
|
|
|
|
+ */
|
|
|
|
+int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
|
|
|
|
+ struct posix_acl **acl)
|
|
|
|
+{
|
|
|
|
+ umode_t mode = inode->i_mode;
|
|
|
|
+ int error;
|
|
|
|
+
|
|
|
|
+ error = posix_acl_equiv_mode(*acl, &mode);
|
|
|
|
+ if (error < 0)
|
|
|
|
+ return error;
|
|
|
|
+ if (error == 0)
|
|
|
|
+ *acl = NULL;
|
|
|
|
+ if (!in_group_p(inode->i_gid) &&
|
|
|
|
+ !capable_wrt_inode_uidgid(inode, CAP_FSETID))
|
|
|
|
+ mode &= ~S_ISGID;
|
|
|
|
+ *mode_p = mode;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(posix_acl_update_mode);
|
|
|
|
+
|
|
|
|
/*
|
2017-11-25 19:39:02 -05:00
|
|
|
* Modify the ACL for the chmod syscall.
|
2017-10-29 01:48:53 -04:00
|
|
|
*/
|
|
|
|
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
index 6c8767fdfc6a2..2d73589f37d64 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/reiserfs/xattr_acl.c
|
|
|
|
+++ b/fs/reiserfs/xattr_acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -286,13 +286,9 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
|
2017-10-29 01:48:53 -04:00
|
|
|
case ACL_TYPE_ACCESS:
|
2017-11-25 19:39:02 -05:00
|
|
|
name = POSIX_ACL_XATTR_ACCESS;
|
2017-10-29 01:48:53 -04:00
|
|
|
if (acl) {
|
|
|
|
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
|
|
|
|
- if (error < 0)
|
|
|
|
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
|
|
|
+ if (error)
|
|
|
|
return error;
|
|
|
|
- else {
|
|
|
|
- if (error == 0)
|
|
|
|
- acl = NULL;
|
|
|
|
- }
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ACL_TYPE_DEFAULT:
|
|
|
|
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
index 306d883d89bc7..4f8e4770229cf 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/xfs/xfs_acl.c
|
|
|
|
+++ b/fs/xfs/xfs_acl.c
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -389,16 +389,9 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
|
2017-10-29 01:48:53 -04:00
|
|
|
|
|
|
|
if (type == ACL_TYPE_ACCESS) {
|
2017-11-25 19:39:02 -05:00
|
|
|
umode_t mode = inode->i_mode;
|
2017-10-29 01:48:53 -04:00
|
|
|
- error = posix_acl_equiv_mode(acl, &mode);
|
|
|
|
-
|
|
|
|
- if (error <= 0) {
|
2017-11-25 19:39:02 -05:00
|
|
|
- posix_acl_release(acl);
|
2017-10-29 01:48:53 -04:00
|
|
|
- acl = NULL;
|
|
|
|
-
|
|
|
|
- if (error < 0)
|
|
|
|
- return error;
|
|
|
|
- }
|
2017-11-25 19:39:02 -05:00
|
|
|
-
|
2017-10-29 01:48:53 -04:00
|
|
|
+ error = posix_acl_update_mode(inode, &mode, &acl);
|
|
|
|
+ if (error)
|
2017-11-25 19:39:02 -05:00
|
|
|
+ goto out_release;
|
2017-10-29 01:48:53 -04:00
|
|
|
error = xfs_set_mode(inode, mode);
|
|
|
|
if (error)
|
2017-11-25 19:39:02 -05:00
|
|
|
goto out_release;
|
2017-10-29 01:48:53 -04:00
|
|
|
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
|
2017-11-25 19:39:02 -05:00
|
|
|
index 7931efe711755..2ae0bba45f124 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/include/linux/posix_acl.h
|
|
|
|
+++ b/include/linux/posix_acl.h
|
2017-11-25 19:39:02 -05:00
|
|
|
@@ -90,6 +90,7 @@ extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t);
|
|
|
|
extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *);
|
|
|
|
extern int posix_acl_create(struct posix_acl **, gfp_t, umode_t *);
|
|
|
|
extern int posix_acl_chmod(struct posix_acl **, gfp_t, umode_t);
|
2017-10-29 01:48:53 -04:00
|
|
|
+extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **);
|
|
|
|
|
2017-11-25 19:39:02 -05:00
|
|
|
extern struct posix_acl *get_posix_acl(struct inode *, int);
|
|
|
|
extern int set_posix_acl(struct inode *, int, struct posix_acl *);
|