diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 66 |
1 files changed, 49 insertions, 17 deletions
diff --git a/fs/namei.c b/fs/namei.c index c6dcb4c8f86c..1b6474687698 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -315,31 +315,22 @@ static inline int do_inode_permission(struct inode *inode, int mask) | |||
315 | } | 315 | } |
316 | 316 | ||
317 | /** | 317 | /** |
318 | * inode_permission - check for access rights to a given inode | 318 | * __inode_permission - Check for access rights to a given inode |
319 | * @inode: inode to check permission on | 319 | * @inode: Inode to check permission on |
320 | * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC, ...) | 320 | * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) |
321 | * | 321 | * |
322 | * Used to check for read/write/execute permissions on an inode. | 322 | * Check for read/write/execute permissions on an inode. |
323 | * We use "fsuid" for this, letting us set arbitrary permissions | ||
324 | * for filesystem access without changing the "normal" uids which | ||
325 | * are used for other things. | ||
326 | * | 323 | * |
327 | * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. | 324 | * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. |
325 | * | ||
326 | * This does not check for a read-only file system. You probably want | ||
327 | * inode_permission(). | ||
328 | */ | 328 | */ |
329 | int inode_permission(struct inode *inode, int mask) | 329 | int __inode_permission(struct inode *inode, int mask) |
330 | { | 330 | { |
331 | int retval; | 331 | int retval; |
332 | 332 | ||
333 | if (unlikely(mask & MAY_WRITE)) { | 333 | if (unlikely(mask & MAY_WRITE)) { |
334 | umode_t mode = inode->i_mode; | ||
335 | |||
336 | /* | ||
337 | * Nobody gets write access to a read-only fs. | ||
338 | */ | ||
339 | if (IS_RDONLY(inode) && | ||
340 | (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) | ||
341 | return -EROFS; | ||
342 | |||
343 | /* | 334 | /* |
344 | * Nobody gets write access to an immutable file. | 335 | * Nobody gets write access to an immutable file. |
345 | */ | 336 | */ |
@@ -359,6 +350,47 @@ int inode_permission(struct inode *inode, int mask) | |||
359 | } | 350 | } |
360 | 351 | ||
361 | /** | 352 | /** |
353 | * sb_permission - Check superblock-level permissions | ||
354 | * @sb: Superblock of inode to check permission on | ||
355 | * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) | ||
356 | * | ||
357 | * Separate out file-system wide checks from inode-specific permission checks. | ||
358 | */ | ||
359 | static int sb_permission(struct super_block *sb, struct inode *inode, int mask) | ||
360 | { | ||
361 | if (unlikely(mask & MAY_WRITE)) { | ||
362 | umode_t mode = inode->i_mode; | ||
363 | |||
364 | /* Nobody gets write access to a read-only fs. */ | ||
365 | if ((sb->s_flags & MS_RDONLY) && | ||
366 | (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) | ||
367 | return -EROFS; | ||
368 | } | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | /** | ||
373 | * inode_permission - Check for access rights to a given inode | ||
374 | * @inode: Inode to check permission on | ||
375 | * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) | ||
376 | * | ||
377 | * Check for read/write/execute permissions on an inode. We use fs[ug]id for | ||
378 | * this, letting us set arbitrary permissions for filesystem access without | ||
379 | * changing the "normal" UIDs which are used for other things. | ||
380 | * | ||
381 | * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. | ||
382 | */ | ||
383 | int inode_permission(struct inode *inode, int mask) | ||
384 | { | ||
385 | int retval; | ||
386 | |||
387 | retval = sb_permission(inode->i_sb, inode, mask); | ||
388 | if (retval) | ||
389 | return retval; | ||
390 | return __inode_permission(inode, mask); | ||
391 | } | ||
392 | |||
393 | /** | ||
362 | * path_get - get a reference to a path | 394 | * path_get - get a reference to a path |
363 | * @path: path to get the reference to | 395 | * @path: path to get the reference to |
364 | * | 396 | * |