diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-08 18:11:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-08 18:11:56 -0400 |
commit | 95f4efb2d78661065aaf0be57f5bf00e4d2aea1d (patch) | |
tree | e344402e6428194515a0550ef30cf7cb8eeb0fdf /security/selinux | |
parent | 4c1f683a4a343808536a5617ede85dfc34430472 (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/selinux')
-rw-r--r-- | security/selinux/hooks.c | 25 |
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 | ||
1492 | static 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 */ |