Exemplo n.º 1
0
/*
 * 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;

	/* The inode may already have been freed, freeing the iint
	 * with it. Verify the inode is not NULL before dereferencing
	 * it.
	 */
	if (!ima_initialized || !inode || !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);

	kref_put(&iint->refcount, iint_free);
}
Exemplo n.º 2
0
static int process_measurement(struct file *file, const unsigned char *filename,
			       int mask, int function)
{
	struct inode *inode = file->f_dentry->d_inode;
	struct ima_iint_cache *iint;
	int rc;

	if (!ima_initialized || !S_ISREG(inode->i_mode))
		return 0;
	iint = ima_iint_find_insert_get(inode);
	if (!iint)
		return -ENOMEM;

	mutex_lock(&iint->mutex);
	rc = ima_must_measure(iint, inode, mask, function);
	if (rc != 0)
		goto out;

	rc = ima_collect_measurement(iint, file);
	if (!rc)
		ima_store_measurement(iint, file, filename);
out:
	mutex_unlock(&iint->mutex);
	kref_put(&iint->refcount, iint_free);
	return rc;
}
Exemplo n.º 3
0
/**
 * ima_path_check - based on policy, collect/store measurement.
 * @path: contains a pointer to the path to be measured
 * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE
 *
 * Measure the file being open for readonly, based on the
 * ima_must_measure() policy decision.
 *
 * Keep read/write counters for all files, but only
 * invalidate the PCR for measured files:
 * 	- Opening a file for write when already open for read,
 *	  results in a time of measure, time of use (ToMToU) error.
 *	- Opening a file for read when already open for write,
 * 	  could result in a file measurement error.
 *
 * Always return 0 and audit dentry_open failures.
 * (Return code will be based upon measurement appraisal.)
 */
int ima_path_check(struct path *path, int mask, int update_counts)
{
	struct inode *inode = path->dentry->d_inode;
	struct ima_iint_cache *iint;
	struct file *file = NULL;
	int rc;

	if (!ima_initialized || !S_ISREG(inode->i_mode))
		return 0;
	iint = ima_iint_find_insert_get(inode);
	if (!iint)
		return 0;

	mutex_lock(&iint->mutex);
	if (update_counts)
		ima_update_counts(iint, mask);

	rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK);
	if (rc < 0)
		goto out;

	if ((mask & MAY_WRITE) || (mask == 0))
		ima_read_write_check(TOMTOU, iint, inode,
				     path->dentry->d_name.name);

	if ((mask & (MAY_WRITE | MAY_READ | MAY_EXEC)) != MAY_READ)
		goto out;

	ima_read_write_check(OPEN_WRITERS, iint, inode,
			     path->dentry->d_name.name);
	if (!(iint->flags & IMA_MEASURED)) {
		struct dentry *dentry = dget(path->dentry);
		struct vfsmount *mnt = mntget(path->mnt);

		file = dentry_open(dentry, mnt, O_RDONLY | O_LARGEFILE,
				   current_cred());
		if (IS_ERR(file)) {
			int audit_info = 0;

			integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
					    dentry->d_name.name,
					    "add_measurement",
					    "dentry_open failed",
					    1, audit_info);
			file = NULL;
			goto out;
		}
		rc = get_path_measurement(iint, file, dentry->d_name.name);
	}
out:
	mutex_unlock(&iint->mutex);
	if (file)
		fput(file);
	kref_put(&iint->refcount, iint_free);
	return 0;
}
Exemplo n.º 4
0
/*
 * ima_counts_get - increment file counts
 *
 * - for IPC shm and shmat file.
 * - for nfsd exported files.
 *
 * Increment the counts for these files to prevent unnecessary
 * imbalance messages.
 */
void ima_counts_get(struct file *file)
{
	struct inode *inode = file->f_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 ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
		iint->readcount++;

	if (file->f_mode & FMODE_WRITE)
		iint->writecount++;
	mutex_unlock(&iint->mutex);
}
Exemplo n.º 5
0
/*
 * 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);
}