[PATCH v3 2/2] ima: audit failure to supply detached data for modsig
From: Jérémy Jean
Date: Wed Oct 21 2026 - 17:03:45 EST
ima_collect_measurement() discards a modsig when detached data cannot be
supplied, but the reason is lost.
Return the pkcs7_supply_detached_data() error from ima_collect_modsig()
and emit a separate failed-modsig audit record. Keep ordinary collection
errors on their existing audit path so both causes are reported when they
happen together.
Signed-off-by: Jérémy Jean <Jeremy.Jean@xxxxxxxxxxxxxxxxx>
---
security/integrity/ima/ima.h | 8 ++++----
security/integrity/ima/ima_api.c | 24 ++++++++++++++++--------
security/integrity/ima/ima_modsig.c | 8 ++++----
3 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 62be9461de88..a899a8195cd4 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -559,7 +559,7 @@ static inline void __init init_ima_appraise_lsm(const struct lsm_id *lsmid)
#ifdef CONFIG_IMA_APPRAISE_MODSIG
int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
struct modsig **modsig);
-bool ima_collect_modsig(struct modsig *modsig, const void *buf, loff_t size);
+int ima_collect_modsig(struct modsig *modsig, const void *buf, loff_t size);
int ima_get_modsig_digest(const struct modsig *modsig, enum hash_algo *algo,
const u8 **digest, u32 *digest_size);
int ima_get_raw_modsig(const struct modsig *modsig, const void **data,
@@ -572,10 +572,10 @@ static inline int ima_read_modsig(enum ima_hooks func, const void *buf,
return -EOPNOTSUPP;
}
-static inline bool ima_collect_modsig(struct modsig *modsig, const void *buf,
- loff_t size)
+static inline int ima_collect_modsig(struct modsig *modsig, const void *buf,
+ loff_t size)
{
- return false;
+ return -EOPNOTSUPP;
}
static inline int ima_get_modsig_digest(const struct modsig *modsig,
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 00b83b4538ab..4add21b4b9d8 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -254,7 +254,7 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file,
struct ima_digest_data, hdr);
struct name_snapshot filename;
struct kstat stat;
- int result = 0;
+ int result = 0, modsig_result = 0;
int length;
void *tmpbuf;
u64 i_version = 0;
@@ -264,9 +264,12 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file,
* the file digest without collecting the modsig in a previous
* measurement rule.
*/
- if (modsig && *modsig && !ima_collect_modsig(*modsig, buf, size)) {
- ima_free_modsig(*modsig);
- *modsig = NULL;
+ if (modsig && *modsig) {
+ modsig_result = ima_collect_modsig(*modsig, buf, size);
+ if (modsig_result) {
+ ima_free_modsig(*modsig);
+ *modsig = NULL;
+ }
}
if (iint->flags & IMA_COLLECTED)
@@ -326,15 +329,20 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file,
if (!result)
iint->flags |= IMA_COLLECTED;
out:
- if (result) {
+ if (result || modsig_result) {
if (file->f_flags & O_DIRECT)
audit_cause = "failed(directio)";
take_dentry_name_snapshot(&filename, file->f_path.dentry);
- integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
- filename.name.name, "collect_data",
- audit_cause, result, 0);
+ if (modsig_result)
+ integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
+ filename.name.name, "collect_data",
+ "failed-modsig", modsig_result, 0);
+ if (result)
+ integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
+ filename.name.name, "collect_data",
+ audit_cause, result, 0);
release_dentry_name_snapshot(&filename);
}
diff --git a/security/integrity/ima/ima_modsig.c b/security/integrity/ima/ima_modsig.c
index f73d6f1b71c0..8bc42edc2f84 100644
--- a/security/integrity/ima/ima_modsig.c
+++ b/security/integrity/ima/ima_modsig.c
@@ -99,9 +99,9 @@ int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
*
* Digest export is best-effort; not all signatures expose a single digest.
*
- * Return: true if the file data was supplied, false otherwise.
+ * Return: 0 if the file data was supplied, error code otherwise.
*/
-bool ima_collect_modsig(struct modsig *modsig, const void *buf, loff_t size)
+int ima_collect_modsig(struct modsig *modsig, const void *buf, loff_t size)
{
int rc;
@@ -113,13 +113,13 @@ bool ima_collect_modsig(struct modsig *modsig, const void *buf, loff_t size)
sizeof(struct module_signature);
rc = pkcs7_supply_detached_data(modsig->pkcs7_msg, buf, size);
if (rc)
- return false;
+ return rc;
/* Digest export failure does not preclude signature verification. */
pkcs7_get_digest(modsig->pkcs7_msg, &modsig->digest,
&modsig->digest_size, &modsig->hash_algo);
- return true;
+ return 0;
}
int ima_modsig_verify(struct key *keyring, const struct modsig *modsig)
--
2.47.3