aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-06-19 13:14:21 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 01:43:13 -0400
commitf4d6ff89d8e54b68a4322388d26d518d6133fa4e (patch)
tree57f4113a7e5ac2cc0e5a713ac31339f72de797ba
parent3bfa784a6539f91a27d7ffdd408efdb638e3bebd (diff)
move exec_permission() up to the rest of permission-related functions
... and convert the comment before it into linuxdoc form. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/namei.c72
1 files changed, 38 insertions, 34 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 4ad2b781a65c..e04f15ae4b07 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -303,6 +303,44 @@ int inode_permission(struct inode *inode, int mask)
303 return security_inode_permission(inode, mask); 303 return security_inode_permission(inode, mask);
304} 304}
305 305
306/**
307 * exec_permission - check for right to do lookups in a given directory
308 * @inode: inode to check permission on
309 * @flags: IPERM_FLAG_ flags.
310 *
311 * Short-cut version of inode_permission(), for calling on directories
312 * during pathname resolution. Combines parts of inode_permission()
313 * and generic_permission(), and tests ONLY for MAY_EXEC permission.
314 *
315 * If appropriate, check DAC only. If not appropriate, or
316 * short-cut DAC fails, then call ->permission() to do more
317 * complete permission check.
318 */
319static inline int exec_permission(struct inode *inode, unsigned int flags)
320{
321 int ret;
322 struct user_namespace *ns = inode_userns(inode);
323
324 if (inode->i_op->permission) {
325 ret = inode->i_op->permission(inode, MAY_EXEC, flags);
326 if (likely(!ret))
327 goto ok;
328 } else {
329 ret = acl_permission_check(inode, MAY_EXEC, flags,
330 inode->i_op->check_acl);
331 if (likely(!ret))
332 goto ok;
333 if (ret != -EACCES)
334 return ret;
335 if (ns_capable(ns, CAP_DAC_OVERRIDE) ||
336 ns_capable(ns, CAP_DAC_READ_SEARCH))
337 goto ok;
338 }
339 return ret;
340ok:
341 return security_inode_exec_permission(inode, flags);
342}
343
306/* 344/*
307 * get_write_access() gets write permission for a file. 345 * get_write_access() gets write permission for a file.
308 * put_write_access() releases this write permission. 346 * put_write_access() releases this write permission.
@@ -551,40 +589,6 @@ static int complete_walk(struct nameidata *nd)
551 return status; 589 return status;
552} 590}
553 591
554/*
555 * Short-cut version of permission(), for calling on directories
556 * during pathname resolution. Combines parts of permission()
557 * and generic_permission(), and tests ONLY for MAY_EXEC permission.
558 *
559 * If appropriate, check DAC only. If not appropriate, or
560 * short-cut DAC fails, then call ->permission() to do more
561 * complete permission check.
562 */
563static inline int exec_permission(struct inode *inode, unsigned int flags)
564{
565 int ret;
566 struct user_namespace *ns = inode_userns(inode);
567
568 if (inode->i_op->permission) {
569 ret = inode->i_op->permission(inode, MAY_EXEC, flags);
570 if (likely(!ret))
571 goto ok;
572 } else {
573 ret = acl_permission_check(inode, MAY_EXEC, flags,
574 inode->i_op->check_acl);
575 if (likely(!ret))
576 goto ok;
577 if (ret != -EACCES)
578 return ret;
579 if (ns_capable(ns, CAP_DAC_OVERRIDE) ||
580 ns_capable(ns, CAP_DAC_READ_SEARCH))
581 goto ok;
582 }
583 return ret;
584ok:
585 return security_inode_exec_permission(inode, flags);
586}
587
588static __always_inline void set_root(struct nameidata *nd) 592static __always_inline void set_root(struct nameidata *nd)
589{ 593{
590 if (!nd->root.mnt) 594 if (!nd->root.mnt)