forked from mirrors/linux
		
	Untangling ima mess, part 2: deal with counters
* do ima_get_count() in __dentry_open() * stop doing that in followups * move ima_path_check() to right after nameidata_to_filp() * don't bump counters on it Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									0552f879d4
								
							
						
					
					
						commit
						b65a9cfc2c
					
				
					 6 changed files with 28 additions and 43 deletions
				
			
		| 
						 | 
					@ -11,7 +11,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/mount.h>
 | 
					#include <linux/mount.h>
 | 
				
			||||||
#include <linux/file.h>
 | 
					#include <linux/file.h>
 | 
				
			||||||
#include <linux/ima.h>
 | 
					 | 
				
			||||||
#include "internal.h"
 | 
					#include "internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -923,7 +922,6 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
 | 
				
			||||||
	if (IS_ERR(file)) {
 | 
						if (IS_ERR(file)) {
 | 
				
			||||||
		ret = PTR_ERR(file);
 | 
							ret = PTR_ERR(file);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		ima_counts_get(file);
 | 
					 | 
				
			||||||
		ret = -EIO;
 | 
							ret = -EIO;
 | 
				
			||||||
		if (file->f_op->write) {
 | 
							if (file->f_op->write) {
 | 
				
			||||||
			pos = (loff_t) page->index << PAGE_SHIFT;
 | 
								pos = (loff_t) page->index << PAGE_SHIFT;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,6 @@
 | 
				
			||||||
#include <linux/key.h>
 | 
					#include <linux/key.h>
 | 
				
			||||||
#include <linux/parser.h>
 | 
					#include <linux/parser.h>
 | 
				
			||||||
#include <linux/fs_stack.h>
 | 
					#include <linux/fs_stack.h>
 | 
				
			||||||
#include <linux/ima.h>
 | 
					 | 
				
			||||||
#include "ecryptfs_kernel.h"
 | 
					#include "ecryptfs_kernel.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -119,7 +118,6 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
 | 
				
			||||||
	const struct cred *cred = current_cred();
 | 
						const struct cred *cred = current_cred();
 | 
				
			||||||
	struct ecryptfs_inode_info *inode_info =
 | 
						struct ecryptfs_inode_info *inode_info =
 | 
				
			||||||
		ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
 | 
							ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
 | 
				
			||||||
	int opened_lower_file = 0;
 | 
					 | 
				
			||||||
	int rc = 0;
 | 
						int rc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&inode_info->lower_file_mutex);
 | 
						mutex_lock(&inode_info->lower_file_mutex);
 | 
				
			||||||
| 
						 | 
					@ -136,12 +134,9 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
 | 
				
			||||||
			       "for lower_dentry [0x%p] and lower_mnt [0x%p]; "
 | 
								       "for lower_dentry [0x%p] and lower_mnt [0x%p]; "
 | 
				
			||||||
			       "rc = [%d]\n", lower_dentry, lower_mnt, rc);
 | 
								       "rc = [%d]\n", lower_dentry, lower_mnt, rc);
 | 
				
			||||||
			inode_info->lower_file = NULL;
 | 
								inode_info->lower_file = NULL;
 | 
				
			||||||
		} else
 | 
							}
 | 
				
			||||||
			opened_lower_file = 1;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mutex_unlock(&inode_info->lower_file_mutex);
 | 
						mutex_unlock(&inode_info->lower_file_mutex);
 | 
				
			||||||
	if (opened_lower_file)
 | 
					 | 
				
			||||||
		ima_counts_get(inode_info->lower_file);
 | 
					 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										56
									
								
								fs/namei.c
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								fs/namei.c
									
									
									
									
									
								
							| 
						 | 
					@ -1461,14 +1461,7 @@ int may_open(struct path *path, int acc_mode, int flag)
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Ensure there are no outstanding leases on the file.
 | 
						 * Ensure there are no outstanding leases on the file.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	error = break_lease(inode, flag);
 | 
						return break_lease(inode, flag);
 | 
				
			||||||
	if (error)
 | 
					 | 
				
			||||||
		return error;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ima_path_check(path, acc_mode ?
 | 
					 | 
				
			||||||
			       acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC) :
 | 
					 | 
				
			||||||
			       ACC_MODE(flag) & (MAY_READ | MAY_WRITE),
 | 
					 | 
				
			||||||
			       IMA_COUNT_UPDATE);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int handle_truncate(struct path *path)
 | 
					static int handle_truncate(struct path *path)
 | 
				
			||||||
| 
						 | 
					@ -1688,13 +1681,17 @@ struct file *do_filp_open(int dfd, const char *pathname,
 | 
				
			||||||
			goto exit;
 | 
								goto exit;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		filp = nameidata_to_filp(&nd, open_flag);
 | 
							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);
 | 
							mnt_drop_write(nd.path.mnt);
 | 
				
			||||||
		if (nd.root.mnt)
 | 
							if (nd.root.mnt)
 | 
				
			||||||
			path_put(&nd.root);
 | 
								path_put(&nd.root);
 | 
				
			||||||
 | 
							if (!IS_ERR(filp)) {
 | 
				
			||||||
 | 
								error = ima_path_check(&filp->f_path, filp->f_mode &
 | 
				
			||||||
 | 
									       (MAY_READ | MAY_WRITE | MAY_EXEC), 0);
 | 
				
			||||||
 | 
								if (error) {
 | 
				
			||||||
 | 
									fput(filp);
 | 
				
			||||||
 | 
									filp = ERR_PTR(error);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return filp;
 | 
							return filp;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1748,27 +1745,24 @@ struct file *do_filp_open(int dfd, const char *pathname,
 | 
				
			||||||
		goto exit;
 | 
							goto exit;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	filp = nameidata_to_filp(&nd, open_flag);
 | 
						filp = nameidata_to_filp(&nd, open_flag);
 | 
				
			||||||
	if (IS_ERR(filp)) {
 | 
						if (!IS_ERR(filp)) {
 | 
				
			||||||
		ima_counts_put(&nd.path,
 | 
							error = ima_path_check(&filp->f_path, filp->f_mode &
 | 
				
			||||||
			       acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC));
 | 
								       (MAY_READ | MAY_WRITE | MAY_EXEC), 0);
 | 
				
			||||||
		if (will_truncate)
 | 
					 | 
				
			||||||
			mnt_drop_write(nd.path.mnt);
 | 
					 | 
				
			||||||
		if (nd.root.mnt)
 | 
					 | 
				
			||||||
			path_put(&nd.root);
 | 
					 | 
				
			||||||
		return filp;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (acc_mode & MAY_WRITE)
 | 
					 | 
				
			||||||
		vfs_dq_init(nd.path.dentry->d_inode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (will_truncate) {
 | 
					 | 
				
			||||||
		error = handle_truncate(&nd.path);
 | 
					 | 
				
			||||||
		if (error) {
 | 
							if (error) {
 | 
				
			||||||
			mnt_drop_write(nd.path.mnt);
 | 
					 | 
				
			||||||
			fput(filp);
 | 
								fput(filp);
 | 
				
			||||||
			if (nd.root.mnt)
 | 
								filp = ERR_PTR(error);
 | 
				
			||||||
				path_put(&nd.root);
 | 
							}
 | 
				
			||||||
			return ERR_PTR(error);
 | 
						}
 | 
				
			||||||
 | 
						if (!IS_ERR(filp)) {
 | 
				
			||||||
 | 
							if (acc_mode & MAY_WRITE)
 | 
				
			||||||
 | 
								vfs_dq_init(nd.path.dentry->d_inode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (will_truncate) {
 | 
				
			||||||
 | 
								error = handle_truncate(&nd.path);
 | 
				
			||||||
 | 
								if (error) {
 | 
				
			||||||
 | 
									fput(filp);
 | 
				
			||||||
 | 
									filp = ERR_PTR(error);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -744,8 +744,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
 | 
				
			||||||
			    flags, current_cred());
 | 
								    flags, current_cred());
 | 
				
			||||||
	if (IS_ERR(*filp))
 | 
						if (IS_ERR(*filp))
 | 
				
			||||||
		host_err = PTR_ERR(*filp);
 | 
							host_err = PTR_ERR(*filp);
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		ima_counts_get(*filp);
 | 
					 | 
				
			||||||
out_nfserr:
 | 
					out_nfserr:
 | 
				
			||||||
	err = nfserrno(host_err);
 | 
						err = nfserrno(host_err);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,7 @@
 | 
				
			||||||
#include <linux/audit.h>
 | 
					#include <linux/audit.h>
 | 
				
			||||||
#include <linux/falloc.h>
 | 
					#include <linux/falloc.h>
 | 
				
			||||||
#include <linux/fs_struct.h>
 | 
					#include <linux/fs_struct.h>
 | 
				
			||||||
 | 
					#include <linux/ima.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "internal.h"
 | 
					#include "internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -857,6 +858,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
 | 
				
			||||||
		if (error)
 | 
							if (error)
 | 
				
			||||||
			goto cleanup_all;
 | 
								goto cleanup_all;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ima_counts_get(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
 | 
						f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,6 @@
 | 
				
			||||||
#include <linux/nsproxy.h>
 | 
					#include <linux/nsproxy.h>
 | 
				
			||||||
#include <linux/pid.h>
 | 
					#include <linux/pid.h>
 | 
				
			||||||
#include <linux/ipc_namespace.h>
 | 
					#include <linux/ipc_namespace.h>
 | 
				
			||||||
#include <linux/ima.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <net/sock.h>
 | 
					#include <net/sock.h>
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
| 
						 | 
					@ -734,7 +733,6 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
 | 
				
			||||||
		error = PTR_ERR(filp);
 | 
							error = PTR_ERR(filp);
 | 
				
			||||||
		goto out_putfd;
 | 
							goto out_putfd;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ima_counts_get(filp);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fd_install(fd, filp);
 | 
						fd_install(fd, filp);
 | 
				
			||||||
	goto out_upsem;
 | 
						goto out_upsem;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue