diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-08 15:11:56 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-08 15:11:56 -0700 | 
| commit | 95f4efb2d78661065aaf0be57f5bf00e4d2aea1d (patch) | |
| tree | e344402e6428194515a0550ef30cf7cb8eeb0fdf /security/selinux/hooks.c | |
| parent | 4c1f683a4a343808536a5617ede85dfc34430472 (diff) | |
| download | olio-linux-3.10-95f4efb2d78661065aaf0be57f5bf00e4d2aea1d.tar.xz olio-linux-3.10-95f4efb2d78661065aaf0be57f5bf00e4d2aea1d.zip  | |
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/hooks.c')
| -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 a0d38459d65..20219ef5439 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -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,15 +1486,21 @@ 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);  } +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     the dentry to help the auditing code to more easily generate the     pathname if needed. */ @@ -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 */  |