From 4cf27141cbe0239f48ec6f0b37bad347d51d1785 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Sun, 19 Jun 2011 01:50:08 -0400
Subject: make exec_permission(dir) really equivalent to inode_permission(dir,
 MAY_EXEC)

capability overrides apply only to the default case; if fs has ->permission()
that does _not_ call generic_permission(), we have no business doing them.
Moreover, if it has ->permission() that does call generic_permission(), we
have no need to recheck capabilities.

Besides, the capability overrides should apply only if we got EACCES from
acl_permission_check(); any other value (-EIO, etc.) should be returned
to caller, capabilities or not capabilities.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/namei.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

(limited to 'fs/namei.c')

diff --git a/fs/namei.c b/fs/namei.c
index 5ba42c453e31..7c8a93042e63 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -584,19 +584,19 @@ static inline int exec_permission(struct inode *inode, unsigned int flags)
 
 	if (inode->i_op->permission) {
 		ret = inode->i_op->permission(inode, MAY_EXEC, flags);
+		if (likely(!ret))
+			goto ok;
 	} else {
 		ret = acl_permission_check(inode, MAY_EXEC, flags,
 				inode->i_op->check_acl);
+		if (likely(!ret))
+			goto ok;
+		if (ret != -EACCES)
+			return ret;
+		if (ns_capable(ns, CAP_DAC_OVERRIDE) ||
+				ns_capable(ns, CAP_DAC_READ_SEARCH))
+			goto ok;
 	}
-	if (likely(!ret))
-		goto ok;
-	if (ret == -ECHILD)
-		return ret;
-
-	if (ns_capable(ns, CAP_DAC_OVERRIDE) ||
-			ns_capable(ns, CAP_DAC_READ_SEARCH))
-		goto ok;
-
 	return ret;
 ok:
 	return security_inode_exec_permission(inode, flags);
-- 
cgit v1.2.3