diff options
| -rw-r--r-- | fs/namei.c | 7 | ||||
| -rw-r--r-- | include/linux/ima.h | 6 | ||||
| -rw-r--r-- | security/integrity/ima/ima_main.c | 29 | 
3 files changed, 41 insertions, 1 deletions
diff --git a/fs/namei.c b/fs/namei.c index 5b961eb71cb..f3c5b278895 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1761,6 +1761,10 @@ do_last:  			goto exit;  		}  		filp = nameidata_to_filp(&nd, open_flag); +		if (IS_ERR(filp)) +			ima_counts_put(&nd.path, +				       acc_mode & (MAY_READ | MAY_WRITE | +						   MAY_EXEC));  		mnt_drop_write(nd.path.mnt);  		if (nd.root.mnt)  			path_put(&nd.root); @@ -1817,6 +1821,9 @@ ok:  		goto exit;  	}  	filp = nameidata_to_filp(&nd, open_flag); +	if (IS_ERR(filp)) +		ima_counts_put(&nd.path, +			       acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC));  	/*  	 * It is now safe to drop the mnt write  	 * because the filp has had a write taken diff --git a/include/linux/ima.h b/include/linux/ima.h index b1b827d091a..0e3f2a4c25f 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -24,6 +24,7 @@ extern int ima_path_check(struct path *path, int mask, int update_counts);  extern void ima_file_free(struct file *file);  extern int ima_file_mmap(struct file *file, unsigned long prot);  extern void ima_counts_get(struct file *file); +extern void ima_counts_put(struct path *path, int mask);  #else  static inline int ima_bprm_check(struct linux_binprm *bprm) @@ -60,5 +61,10 @@ static inline void ima_counts_get(struct file *file)  {  	return;  } + +static inline void ima_counts_put(struct path *path, int mask) +{ +	return; +}  #endif /* CONFIG_IMA_H */  #endif /* _LINUX_IMA_H */ diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 6f611874d10..101c512564e 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -238,7 +238,34 @@ out:  }  /* - * ima_opens_get - increment file counts + * ima_counts_put - decrement file counts + * + * File counts are incremented in ima_path_check. On file open + * error, such as ETXTBSY, decrement the counts to prevent + * unnecessary imbalance messages. + */ +void ima_counts_put(struct path *path, int mask) +{ +	struct inode *inode = path->dentry->d_inode; +	struct ima_iint_cache *iint; + +	if (!ima_initialized || !S_ISREG(inode->i_mode)) +		return; +	iint = ima_iint_find_insert_get(inode); +	if (!iint) +		return; + +	mutex_lock(&iint->mutex); +	iint->opencount--; +	if ((mask & MAY_WRITE) || (mask == 0)) +		iint->writecount--; +	else if (mask & (MAY_READ | MAY_EXEC)) +		iint->readcount--; +	mutex_unlock(&iint->mutex); +} + +/* + * ima_counts_get - increment file counts   *   * - for IPC shm and shmat file.   * - for nfsd exported files.  |