Commit 95f4efb2 authored by Linus Torvalds's avatar Linus Torvalds

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: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 4c1f683a
...@@ -1476,7 +1476,6 @@ static int inode_has_perm(const struct cred *cred, ...@@ -1476,7 +1476,6 @@ static int inode_has_perm(const struct cred *cred,
unsigned flags) unsigned flags)
{ {
struct inode_security_struct *isec; struct inode_security_struct *isec;
struct common_audit_data ad;
u32 sid; u32 sid;
validate_creds(cred); validate_creds(cred);
...@@ -1487,15 +1486,21 @@ static int inode_has_perm(const struct cred *cred, ...@@ -1487,15 +1486,21 @@ static int inode_has_perm(const struct cred *cred,
sid = cred_sid(cred); sid = cred_sid(cred);
isec = inode->i_security; 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 /* Same as inode_has_perm, but pass explicit audit data containing
the dentry to help the auditing code to more easily generate the the dentry to help the auditing code to more easily generate the
pathname if needed. */ pathname if needed. */
...@@ -2122,8 +2127,8 @@ static inline void flush_unauthorized_files(const struct cred *cred, ...@@ -2122,8 +2127,8 @@ static inline void flush_unauthorized_files(const struct cred *cred,
struct tty_file_private, list); struct tty_file_private, list);
file = file_priv->file; file = file_priv->file;
inode = file->f_path.dentry->d_inode; inode = file->f_path.dentry->d_inode;
if (inode_has_perm(cred, inode, if (inode_has_perm_noadp(cred, inode,
FILE__READ | FILE__WRITE, NULL, 0)) { FILE__READ | FILE__WRITE, 0)) {
drop_tty = 1; drop_tty = 1;
} }
} }
...@@ -3228,7 +3233,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred) ...@@ -3228,7 +3233,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
* new inode label or new policy. * new inode label or new policy.
* This check is not redundant - do not remove. * 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 */ /* task security operations */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment