Skip to content

Commit 95f4efb

Browse files
committed
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 <[email protected]>
1 parent 4c1f683 commit 95f4efb

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

security/selinux/hooks.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,6 @@ static int inode_has_perm(const struct cred *cred,
14761476
unsigned flags)
14771477
{
14781478
struct inode_security_struct *isec;
1479-
struct common_audit_data ad;
14801479
u32 sid;
14811480

14821481
validate_creds(cred);
@@ -1487,15 +1486,21 @@ static int inode_has_perm(const struct cred *cred,
14871486
sid = cred_sid(cred);
14881487
isec = inode->i_security;
14891488

1490-
if (!adp) {
1491-
adp = &ad;
1492-
COMMON_AUDIT_DATA_INIT(&ad, INODE);
1493-
ad.u.inode = inode;
1494-
}
1495-
14961489
return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
14971490
}
14981491

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+
14991504
/* Same as inode_has_perm, but pass explicit audit data containing
15001505
the dentry to help the auditing code to more easily generate the
15011506
pathname if needed. */
@@ -2122,8 +2127,8 @@ static inline void flush_unauthorized_files(const struct cred *cred,
21222127
struct tty_file_private, list);
21232128
file = file_priv->file;
21242129
inode = file->f_path.dentry->d_inode;
2125-
if (inode_has_perm(cred, inode,
2126-
FILE__READ | FILE__WRITE, NULL, 0)) {
2130+
if (inode_has_perm_noadp(cred, inode,
2131+
FILE__READ | FILE__WRITE, 0)) {
21272132
drop_tty = 1;
21282133
}
21292134
}
@@ -3228,7 +3233,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
32283233
* new inode label or new policy.
32293234
* This check is not redundant - do not remove.
32303235
*/
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);
32323237
}
32333238

32343239
/* task security operations */

0 commit comments

Comments
 (0)