aboutsummaryrefslogtreecommitdiffstats
path: root/fs/orangefs
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2017-06-22 09:31:13 -0400
committerMike Marshall <hubcap@omnibond.com>2017-09-14 14:54:37 -0400
commitb5accbb0dfae36d8d36cd882096943c98d5ede15 (patch)
tree0f546045e8ab5b3dd2bfcd49762fca6845bd0418 /fs/orangefs
parent569dbb88e80deb68974ef6fdd6a13edb9d686261 (diff)
orangefs: Don't clear SGID when inheriting ACLs
When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit set, DIR1 is expected to have SGID bit set (and owning group equal to the owning group of 'DIR0'). However when 'DIR0' also has some default ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on 'DIR1' to get cleared if user is not member of the owning group. Fix the problem by creating __orangefs_set_acl() function that does not call posix_acl_update_mode() and use it when inheriting ACLs. That prevents SGID bit clearing and the mode has been properly set by posix_acl_create() anyway. Fixes: 073931017b49d9458aa351605b43a7e34598caef CC: stable@vger.kernel.org CC: Mike Marshall <hubcap@omnibond.com> CC: pvfs2-developers@beowulf-underground.org Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Mike Marshall <hubcap@omnibond.com>
Diffstat (limited to 'fs/orangefs')
-rw-r--r--fs/orangefs/acl.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c
index 7a3754488312..9409aac232f7 100644
--- a/fs/orangefs/acl.c
+++ b/fs/orangefs/acl.c
@@ -61,9 +61,9 @@ struct posix_acl *orangefs_get_acl(struct inode *inode, int type)
61 return acl; 61 return acl;
62} 62}
63 63
64int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) 64static int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl,
65 int type)
65{ 66{
66 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
67 int error = 0; 67 int error = 0;
68 void *value = NULL; 68 void *value = NULL;
69 size_t size = 0; 69 size_t size = 0;
@@ -72,22 +72,6 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
72 switch (type) { 72 switch (type) {
73 case ACL_TYPE_ACCESS: 73 case ACL_TYPE_ACCESS:
74 name = XATTR_NAME_POSIX_ACL_ACCESS; 74 name = XATTR_NAME_POSIX_ACL_ACCESS;
75 if (acl) {
76 umode_t mode;
77
78 error = posix_acl_update_mode(inode, &mode, &acl);
79 if (error) {
80 gossip_err("%s: posix_acl_update_mode err: %d\n",
81 __func__,
82 error);
83 return error;
84 }
85
86 if (inode->i_mode != mode)
87 SetModeFlag(orangefs_inode);
88 inode->i_mode = mode;
89 mark_inode_dirty_sync(inode);
90 }
91 break; 75 break;
92 case ACL_TYPE_DEFAULT: 76 case ACL_TYPE_DEFAULT:
93 name = XATTR_NAME_POSIX_ACL_DEFAULT; 77 name = XATTR_NAME_POSIX_ACL_DEFAULT;
@@ -132,6 +116,29 @@ out:
132 return error; 116 return error;
133} 117}
134 118
119int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
120{
121 int error;
122
123 if (type == ACL_TYPE_ACCESS && acl) {
124 umode_t mode;
125
126 error = posix_acl_update_mode(inode, &mode, &acl);
127 if (error) {
128 gossip_err("%s: posix_acl_update_mode err: %d\n",
129 __func__,
130 error);
131 return error;
132 }
133
134 if (inode->i_mode != mode)
135 SetModeFlag(ORANGEFS_I(inode));
136 inode->i_mode = mode;
137 mark_inode_dirty_sync(inode);
138 }
139 return __orangefs_set_acl(inode, acl, type);
140}
141
135int orangefs_init_acl(struct inode *inode, struct inode *dir) 142int orangefs_init_acl(struct inode *inode, struct inode *dir)
136{ 143{
137 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 144 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
@@ -146,13 +153,14 @@ int orangefs_init_acl(struct inode *inode, struct inode *dir)
146 return error; 153 return error;
147 154
148 if (default_acl) { 155 if (default_acl) {
149 error = orangefs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); 156 error = __orangefs_set_acl(inode, default_acl,
157 ACL_TYPE_DEFAULT);
150 posix_acl_release(default_acl); 158 posix_acl_release(default_acl);
151 } 159 }
152 160
153 if (acl) { 161 if (acl) {
154 if (!error) 162 if (!error)
155 error = orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS); 163 error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
156 posix_acl_release(acl); 164 posix_acl_release(acl);
157 } 165 }
158 166