aboutsummaryrefslogtreecommitdiff
path: root/security/integrity/ima/ima_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity/ima/ima_api.c')
-rw-r--r--security/integrity/ima/ima_api.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index c35ea613c9f8..0916f24f005f 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -11,6 +11,7 @@
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/fs.h>
+#include <linux/hex.h>
#include <linux/xattr.h>
#include <linux/evm.h>
#include <linux/fsverity.h>
@@ -47,13 +48,14 @@ int ima_alloc_init_template(struct ima_event_data *event_data,
else
template_desc = ima_template_desc_current();
- *entry = kzalloc(struct_size(*entry, template_data,
- template_desc->num_fields), GFP_NOFS);
+ *entry = kzalloc_flex(**entry, template_data, template_desc->num_fields,
+ GFP_NOFS);
if (!*entry)
return -ENOMEM;
- digests = kcalloc(NR_BANKS(ima_tpm_chip) + ima_extra_slots,
- sizeof(*digests), GFP_NOFS);
+ digests = kzalloc_objs(*digests,
+ NR_BANKS(ima_tpm_chip) + ima_extra_slots,
+ GFP_NOFS);
if (!digests) {
kfree(*entry);
*entry = NULL;
@@ -267,15 +269,20 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file,
goto out;
/*
- * Detecting file change is based on i_version. On filesystems
- * which do not support i_version, support was originally limited
- * to an initial measurement/appraisal/audit, but was modified to
- * assume the file changed.
+ * Detect file change based on STATX_CHANGE_COOKIE, when supported,
+ * and fallback to detecting file change based on i_version.
+ *
+ * On filesystems which did not support i_version, support was
+ * originally limited to an initial measurement/appraisal/audit,
+ * but was later modified to assume the file changed.
*/
result = vfs_getattr_nosec(&file->f_path, &stat, STATX_CHANGE_COOKIE,
AT_STATX_SYNC_AS_STAT);
if (!result && (stat.result_mask & STATX_CHANGE_COOKIE))
i_version = stat.change_cookie;
+ else if (IS_I_VERSION(real_inode))
+ i_version = inode_peek_iversion(real_inode);
+
hash.hdr.algo = algo;
hash.hdr.length = hash_digest_size[algo];