aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity/ima/ima_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity/ima/ima_main.c')
-rw-r--r--security/integrity/ima/ima_main.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index c6412dec3810..3d3f8c5c502b 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -418,6 +418,7 @@ int ima_file_mmap(struct file *file, unsigned long prot)
/**
* ima_file_mprotect - based on policy, limit mprotect change
+ * @vma: vm_area_struct protection is set to
* @prot: contains the protection that will be applied by the kernel.
*
* Files can be mmap'ed read/write and later changed to execute to circumvent
@@ -519,20 +520,38 @@ int ima_file_check(struct file *file, int mask)
}
EXPORT_SYMBOL_GPL(ima_file_check);
-static int __ima_inode_hash(struct inode *inode, char *buf, size_t buf_size)
+static int __ima_inode_hash(struct inode *inode, struct file *file, char *buf,
+ size_t buf_size)
{
- struct integrity_iint_cache *iint;
- int hash_algo;
+ struct integrity_iint_cache *iint = NULL, tmp_iint;
+ int rc, hash_algo;
- if (!ima_policy_flag)
- return -EOPNOTSUPP;
+ if (ima_policy_flag) {
+ iint = integrity_iint_find(inode);
+ if (iint)
+ mutex_lock(&iint->mutex);
+ }
+
+ if ((!iint || !(iint->flags & IMA_COLLECTED)) && file) {
+ if (iint)
+ mutex_unlock(&iint->mutex);
+
+ memset(&tmp_iint, 0, sizeof(tmp_iint));
+ tmp_iint.inode = inode;
+ mutex_init(&tmp_iint.mutex);
+
+ rc = ima_collect_measurement(&tmp_iint, file, NULL, 0,
+ ima_hash_algo, NULL);
+ if (rc < 0)
+ return -EOPNOTSUPP;
+
+ iint = &tmp_iint;
+ mutex_lock(&iint->mutex);
+ }
- iint = integrity_iint_find(inode);
if (!iint)
return -EOPNOTSUPP;
- mutex_lock(&iint->mutex);
-
/*
* ima_file_hash can be called when ima_collect_measurement has still
* not been called, we might not always have a hash.
@@ -551,12 +570,14 @@ static int __ima_inode_hash(struct inode *inode, char *buf, size_t buf_size)
hash_algo = iint->ima_hash->algo;
mutex_unlock(&iint->mutex);
+ if (iint == &tmp_iint)
+ kfree(iint->ima_hash);
+
return hash_algo;
}
/**
- * ima_file_hash - return the stored measurement if a file has been hashed and
- * is in the iint cache.
+ * ima_file_hash - return a measurement of the file
* @file: pointer to the file
* @buf: buffer in which to store the hash
* @buf_size: length of the buffer
@@ -569,7 +590,7 @@ static int __ima_inode_hash(struct inode *inode, char *buf, size_t buf_size)
* The file hash returned is based on the entire file, including the appended
* signature.
*
- * If IMA is disabled or if no measurement is available, return -EOPNOTSUPP.
+ * If the measurement cannot be performed, return -EOPNOTSUPP.
* If the parameters are incorrect, return -EINVAL.
*/
int ima_file_hash(struct file *file, char *buf, size_t buf_size)
@@ -577,7 +598,7 @@ int ima_file_hash(struct file *file, char *buf, size_t buf_size)
if (!file)
return -EINVAL;
- return __ima_inode_hash(file_inode(file), buf, buf_size);
+ return __ima_inode_hash(file_inode(file), file, buf, buf_size);
}
EXPORT_SYMBOL_GPL(ima_file_hash);
@@ -604,14 +625,14 @@ int ima_inode_hash(struct inode *inode, char *buf, size_t buf_size)
if (!inode)
return -EINVAL;
- return __ima_inode_hash(inode, buf, buf_size);
+ return __ima_inode_hash(inode, NULL, buf, buf_size);
}
EXPORT_SYMBOL_GPL(ima_inode_hash);
/**
* ima_post_create_tmpfile - mark newly created tmpfile as new
- * @mnt_userns: user namespace of the mount the inode was found from
- * @file : newly created tmpfile
+ * @mnt_userns: user namespace of the mount the inode was found from
+ * @inode: inode of the newly created tmpfile
*
* No measuring, appraising or auditing of newly created tmpfiles is needed.
* Skip calling process_measurement(), but indicate which newly, created
@@ -643,7 +664,7 @@ void ima_post_create_tmpfile(struct user_namespace *mnt_userns,
/**
* ima_post_path_mknod - mark as a new inode
- * @mnt_userns: user namespace of the mount the inode was found from
+ * @mnt_userns: user namespace of the mount the inode was found from
* @dentry: newly created dentry
*
* Mark files created via the mknodat syscall as new, so that the
@@ -814,8 +835,8 @@ int ima_load_data(enum kernel_load_data_id id, bool contents)
* ima_post_load_data - appraise decision based on policy
* @buf: pointer to in memory file contents
* @size: size of in memory file contents
- * @id: kernel load data caller identifier
- * @description: @id-specific description of contents
+ * @load_id: kernel load data caller identifier
+ * @description: @load_id-specific description of contents
*
* Measure/appraise/audit in memory buffer based on policy. Policy rules
* are written in terms of a policy identifier.