aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-06-08 18:11:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-06-08 18:11:56 -0400
commit95f4efb2d78661065aaf0be57f5bf00e4d2aea1d (patch)
treee344402e6428194515a0550ef30cf7cb8eeb0fdf /security
parent4c1f683a4a343808536a5617ede85dfc34430472 (diff)
selinux: simplify and clean up inode_has_perm()
This is a rather hot function that is called with a potentially NULL "struct common_audit_data" pointer argument. And in that case it has to provide and initialize its own dummy common_audit_data structure. However, all the _common_ cases already pass it a real audit-data structure, so that uncommon NULL case not only creates a silly run-time test, more importantly it causes that function to have a big stack frame for the dummy variable that isn't even used in the common case! So get rid of that stupid run-time behavior, and make the (few) functions that currently call with a NULL pointer just call a new helper function instead (naturally called inode_has_perm_noapd(), since it has no adp argument). This makes the run-time test be a static code generation issue instead, and allows for a much denser stack since none of the common callers need the dummy structure. And a denser stack not only means less stack space usage, it means better cache behavior. So we have a win-win-win from this simplification: less code executed, smaller stack footprint, and better cache behavior. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index a0d38459d650..20219ef5439a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1476,7 +1476,6 @@ static int inode_has_perm(const struct cred *cred,
1476 unsigned flags) 1476 unsigned flags)
1477{ 1477{
1478 struct inode_security_struct *isec; 1478 struct inode_security_struct *isec;
1479 struct common_audit_data ad;
1480 u32 sid; 1479 u32 sid;
1481 1480
1482 validate_creds(cred); 1481 validate_creds(cred);
@@ -1487,15 +1486,21 @@ static int inode_has_perm(const struct cred *cred,
1487 sid = cred_sid(cred); 1486 sid = cred_sid(cred);
1488 isec = inode->i_security; 1487 isec = inode->i_security;
1489 1488
1490 if (!adp) {
1491 adp = &ad;
1492 COMMON_AUDIT_DATA_INIT(&ad, INODE);
1493 ad.u.inode = inode;
1494 }
1495
1496 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); 1489 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
1497} 1490}
1498 1491
1492static int inode_has_perm_noadp(const struct cred *cred,
1493 struct inode *inode,
1494 u32 perms,
1495 unsigned flags)
1496{
1497 struct common_audit_data ad;
1498
1499 COMMON_AUDIT_DATA_INIT(&ad, INODE);
1500 ad.u.inode = inode;
1501 return inode_has_perm(cred, inode, perms, &ad, flags);
1502}
1503
1499/* Same as inode_has_perm, but pass explicit audit data containing 1504/* Same as inode_has_perm, but pass explicit audit data containing
1500 the dentry to help the auditing code to more easily generate the 1505 the dentry to help the auditing code to more easily generate the
1501 pathname if needed. */ 1506 pathname if needed. */
@@ -2122,8 +2127,8 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2122 struct tty_file_private, list); 2127 struct tty_file_private, list);
2123 file = file_priv->file; 2128 file = file_priv->file;
2124 inode = file->f_path.dentry->d_inode; 2129 inode = file->f_path.dentry->d_inode;
2125 if (inode_has_perm(cred, inode, 2130 if (inode_has_perm_noadp(cred, inode,
2126 FILE__READ | FILE__WRITE, NULL, 0)) { 2131 FILE__READ | FILE__WRITE, 0)) {
2127 drop_tty = 1; 2132 drop_tty = 1;
2128 } 2133 }
2129 } 2134 }
@@ -3228,7 +3233,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
3228 * new inode label or new policy. 3233 * new inode label or new policy.
3229 * This check is not redundant - do not remove. 3234 * This check is not redundant - do not remove.
3230 */ 3235 */
3231 return inode_has_perm(cred, inode, open_file_to_av(file), NULL, 0); 3236 return inode_has_perm_noadp(cred, inode, open_file_to_av(file), 0);
3232} 3237}
3233 3238
3234/* task security operations */ 3239/* task security operations */