diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 17 | 
1 files changed, 15 insertions, 2 deletions
| diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 15c2a08a66f1..8d8b69c5664e 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1285,6 +1285,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent  		rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,  					   context, len);  		if (rc == -ERANGE) { +			kfree(context); +  			/* Need a larger buffer.  Query for the right size. */  			rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,  						   NULL, 0); @@ -1292,7 +1294,6 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent  				dput(dentry);  				goto out_unlock;  			} -			kfree(context);  			len = rc;  			context = kmalloc(len+1, GFP_NOFS);  			if (!context) { @@ -3029,9 +3030,21 @@ static int selinux_file_mmap(struct file *file, unsigned long reqprot,  	int rc = 0;  	u32 sid = current_sid(); -	if (addr < mmap_min_addr) +	/* +	 * notice that we are intentionally putting the SELinux check before +	 * the secondary cap_file_mmap check.  This is such a likely attempt +	 * at bad behaviour/exploit that we always want to get the AVC, even +	 * if DAC would have also denied the operation. +	 */ +	if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {  		rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,  				  MEMPROTECT__MMAP_ZERO, NULL); +		if (rc) +			return rc; +	} + +	/* do DAC check on address space usage */ +	rc = cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);  	if (rc || addr_only)  		return rc; | 
