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>
This commit is contained in:
parent
4c1f683a4a
commit
95f4efb2d7
@ -1476,7 +1476,6 @@ static int inode_has_perm(const struct cred *cred,
|
||||
unsigned flags)
|
||||
{
|
||||
struct inode_security_struct *isec;
|
||||
struct common_audit_data ad;
|
||||
u32 sid;
|
||||
|
||||
validate_creds(cred);
|
||||
@ -1487,13 +1486,19 @@ static int inode_has_perm(const struct cred *cred,
|
||||
sid = cred_sid(cred);
|
||||
isec = inode->i_security;
|
||||
|
||||
if (!adp) {
|
||||
adp = &ad;
|
||||
COMMON_AUDIT_DATA_INIT(&ad, INODE);
|
||||
ad.u.inode = inode;
|
||||
return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
|
||||
}
|
||||
|
||||
return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
|
||||
static int inode_has_perm_noadp(const struct cred *cred,
|
||||
struct inode *inode,
|
||||
u32 perms,
|
||||
unsigned flags)
|
||||
{
|
||||
struct common_audit_data ad;
|
||||
|
||||
COMMON_AUDIT_DATA_INIT(&ad, INODE);
|
||||
ad.u.inode = inode;
|
||||
return inode_has_perm(cred, inode, perms, &ad, flags);
|
||||
}
|
||||
|
||||
/* Same as inode_has_perm, but pass explicit audit data containing
|
||||
@ -2122,8 +2127,8 @@ static inline void flush_unauthorized_files(const struct cred *cred,
|
||||
struct tty_file_private, list);
|
||||
file = file_priv->file;
|
||||
inode = file->f_path.dentry->d_inode;
|
||||
if (inode_has_perm(cred, inode,
|
||||
FILE__READ | FILE__WRITE, NULL, 0)) {
|
||||
if (inode_has_perm_noadp(cred, inode,
|
||||
FILE__READ | FILE__WRITE, 0)) {
|
||||
drop_tty = 1;
|
||||
}
|
||||
}
|
||||
@ -3228,7 +3233,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
|
||||
* new inode label or new policy.
|
||||
* This check is not redundant - do not remove.
|
||||
*/
|
||||
return inode_has_perm(cred, inode, open_file_to_av(file), NULL, 0);
|
||||
return inode_has_perm_noadp(cred, inode, open_file_to_av(file), 0);
|
||||
}
|
||||
|
||||
/* task security operations */
|
||||
|
Loading…
Reference in New Issue
Block a user