aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 3b26a240ade9..46af98ed136b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -185,6 +185,8 @@ int generic_permission(struct inode *inode, int mask,
185{ 185{
186 umode_t mode = inode->i_mode; 186 umode_t mode = inode->i_mode;
187 187
188 mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
189
188 if (current->fsuid == inode->i_uid) 190 if (current->fsuid == inode->i_uid)
189 mode >>= 6; 191 mode >>= 6;
190 else { 192 else {
@@ -203,7 +205,7 @@ int generic_permission(struct inode *inode, int mask,
203 /* 205 /*
204 * If the DACs are ok we don't need any capability check. 206 * If the DACs are ok we don't need any capability check.
205 */ 207 */
206 if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)) 208 if ((mask & ~mode) == 0)
207 return 0; 209 return 0;
208 210
209 check_capabilities: 211 check_capabilities:
@@ -228,7 +230,7 @@ int generic_permission(struct inode *inode, int mask,
228 230
229int permission(struct inode *inode, int mask, struct nameidata *nd) 231int permission(struct inode *inode, int mask, struct nameidata *nd)
230{ 232{
231 int retval, submask; 233 int retval;
232 struct vfsmount *mnt = NULL; 234 struct vfsmount *mnt = NULL;
233 235
234 if (nd) 236 if (nd)
@@ -261,9 +263,17 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
261 } 263 }
262 264
263 /* Ordinary permission routines do not understand MAY_APPEND. */ 265 /* Ordinary permission routines do not understand MAY_APPEND. */
264 submask = mask & ~MAY_APPEND;
265 if (inode->i_op && inode->i_op->permission) { 266 if (inode->i_op && inode->i_op->permission) {
266 retval = inode->i_op->permission(inode, submask, nd); 267 int extra = 0;
268 if (nd) {
269 if (nd->flags & LOOKUP_ACCESS)
270 extra |= MAY_ACCESS;
271 if (nd->flags & LOOKUP_CHDIR)
272 extra |= MAY_CHDIR;
273 if (nd->flags & LOOKUP_OPEN)
274 extra |= MAY_OPEN;
275 }
276 retval = inode->i_op->permission(inode, mask | extra);
267 if (!retval) { 277 if (!retval) {
268 /* 278 /*
269 * Exec permission on a regular file is denied if none 279 * Exec permission on a regular file is denied if none
@@ -277,7 +287,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
277 return -EACCES; 287 return -EACCES;
278 } 288 }
279 } else { 289 } else {
280 retval = generic_permission(inode, submask, NULL); 290 retval = generic_permission(inode, mask, NULL);
281 } 291 }
282 if (retval) 292 if (retval)
283 return retval; 293 return retval;
@@ -286,7 +296,8 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
286 if (retval) 296 if (retval)
287 return retval; 297 return retval;
288 298
289 return security_inode_permission(inode, mask, nd); 299 return security_inode_permission(inode,
300 mask & (MAY_READ|MAY_WRITE|MAY_EXEC), nd);
290} 301}
291 302
292/** 303/**