public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 1/2] selinux: merge selinux_inode_permission and inode_has_perm
@ 2013-06-03 18:59 Eric Paris
  2013-06-03 18:59 ` [RFC PATCH 2/2] SELinux: cache inode checks inside struct inode Eric Paris
  2013-06-03 19:33 ` [RFC PATCH 1/2] selinux: merge selinux_inode_permission and inode_has_perm Eric Paris
  0 siblings, 2 replies; 8+ messages in thread
From: Eric Paris @ 2013-06-03 18:59 UTC (permalink / raw)
  To: torvalds; +Cc: sds, linux-kernel, selinux, Eric Paris

selinux_inode_permission had some heavy lifting done to make it more
performance polite.  But it still does largely the same thing as
inode_has_perm.  So move that work into inode_has_perm and call
inode_has_perm from selinux_inode_permission.

Signed-off-by: Eric Paris <eparis@redhat.com>
---
 security/selinux/hooks.c | 92 ++++++++++++++++++++++--------------------------
 1 file changed, 42 insertions(+), 50 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5c6f2cd..cfecb52 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1494,17 +1494,41 @@ static int task_has_system(struct task_struct *tsk,
 			    SECCLASS_SYSTEM, perms, NULL);
 }
 
+static noinline int audit_inode_permission(struct inode *inode,
+					   struct common_audit_data *adp,
+					   u32 perms, u32 audited, u32 denied,
+					   unsigned flags)
+{
+	struct common_audit_data ad;
+	struct inode_security_struct *isec = inode->i_security;
+	int rc;
+
+	if (!adp) {
+		ad.type = LSM_AUDIT_DATA_INODE;
+		ad.u.inode = inode;
+		adp = &ad;
+	}
+
+	rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms,
+			    audited, denied, adp, flags);
+	if (rc)
+		return rc;
+	return 0;
+}
+
 /* Check whether a task has a particular permission to an inode.
    The 'adp' parameter is optional and allows other audit
    data to be passed (e.g. the dentry). */
 static int inode_has_perm(const struct cred *cred,
 			  struct inode *inode,
-			  u32 perms,
+			  u32 perms, u32 dontaudit,
 			  struct common_audit_data *adp,
 			  unsigned flags)
 {
 	struct inode_security_struct *isec;
-	u32 sid;
+	struct av_decision avd;
+	u32 sid, denied, audited;
+	int rc, rc2;
 
 	validate_creds(cred);
 
@@ -1514,6 +1538,14 @@ static int inode_has_perm(const struct cred *cred,
 	sid = cred_sid(cred);
 	isec = inode->i_security;
 
+	rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd);
+	audited = avc_audit_required(perms, &avd, rc, dontaudit, &denied);
+	if (likely(!audited))
+		return rc;
+
+	rc2 = audit_inode_permission(inode, adp, perms, audited, denied, flags);
+	if (rc2)
+		return rc2;
 	return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
 }
 
@@ -1529,7 +1561,7 @@ static inline int dentry_has_perm(const struct cred *cred,
 
 	ad.type = LSM_AUDIT_DATA_DENTRY;
 	ad.u.dentry = dentry;
-	return inode_has_perm(cred, inode, av, &ad, 0);
+	return inode_has_perm(cred, inode, av, 0, &ad, 0);
 }
 
 /* Same as inode_has_perm, but pass explicit audit data containing
@@ -1544,7 +1576,7 @@ static inline int path_has_perm(const struct cred *cred,
 
 	ad.type = LSM_AUDIT_DATA_PATH;
 	ad.u.path = *path;
-	return inode_has_perm(cred, inode, av, &ad, 0);
+	return inode_has_perm(cred, inode, av, 0, &ad, 0);
 }
 
 /* Check whether a task can use an open file descriptor to
@@ -1580,7 +1612,7 @@ static int file_has_perm(const struct cred *cred,
 	/* av is zero if only checking access to the descriptor. */
 	rc = 0;
 	if (av)
-		rc = inode_has_perm(cred, inode, av, &ad, 0);
+		rc = inode_has_perm(cred, inode, av, 0, &ad, 0);
 
 out:
 	return rc;
@@ -2635,64 +2667,24 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
 	return dentry_has_perm(cred, dentry, FILE__READ);
 }
 
-static noinline int audit_inode_permission(struct inode *inode,
-					   u32 perms, u32 audited, u32 denied,
-					   unsigned flags)
-{
-	struct common_audit_data ad;
-	struct inode_security_struct *isec = inode->i_security;
-	int rc;
-
-	ad.type = LSM_AUDIT_DATA_INODE;
-	ad.u.inode = inode;
-
-	rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms,
-			    audited, denied, &ad, flags);
-	if (rc)
-		return rc;
-	return 0;
-}
-
 static int selinux_inode_permission(struct inode *inode, int mask)
 {
 	const struct cred *cred = current_cred();
-	u32 perms;
-	bool from_access;
+	u32 perms, dontaudit = 0;
 	unsigned flags = mask & MAY_NOT_BLOCK;
-	struct inode_security_struct *isec;
-	u32 sid;
-	struct av_decision avd;
-	int rc, rc2;
-	u32 audited, denied;
 
-	from_access = mask & MAY_ACCESS;
+	if (mask & MAY_ACCESS)
+		dontaudit = FILE__AUDIT_ACCESS;
+
 	mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
 
 	/* No permission to check.  Existence test. */
 	if (!mask)
 		return 0;
 
-	validate_creds(cred);
-
-	if (unlikely(IS_PRIVATE(inode)))
-		return 0;
-
 	perms = file_mask_to_av(inode->i_mode, mask);
 
-	sid = cred_sid(cred);
-	isec = inode->i_security;
-
-	rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd);
-	audited = avc_audit_required(perms, &avd, rc,
-				     from_access ? FILE__AUDIT_ACCESS : 0,
-				     &denied);
-	if (likely(!audited))
-		return rc;
-
-	rc2 = audit_inode_permission(inode, perms, audited, denied, flags);
-	if (rc2)
-		return rc2;
-	return rc;
+	return inode_has_perm(cred, inode, perms, dontaudit, NULL, flags);
 }
 
 static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
-- 
1.8.2.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-06-04  2:53 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-03 18:59 [RFC PATCH 1/2] selinux: merge selinux_inode_permission and inode_has_perm Eric Paris
2013-06-03 18:59 ` [RFC PATCH 2/2] SELinux: cache inode checks inside struct inode Eric Paris
2013-06-03 20:26   ` Casey Schaufler
2013-06-04  1:00     ` Casey Schaufler
2013-06-03 21:31   ` Linus Torvalds
2013-06-03 23:18     ` Eric Paris
2013-06-04  2:52       ` Casey Schaufler
2013-06-03 19:33 ` [RFC PATCH 1/2] selinux: merge selinux_inode_permission and inode_has_perm Eric Paris

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox