Add modsig support to the "sig" template field, allowing the the contents
of the modsig to be included in the measurement list.

Suggested-by: Mimi Zohar <zo...@linux.ibm.com>
Signed-off-by: Thiago Jung Bauermann <bauer...@linux.ibm.com>
---
 security/integrity/ima/ima.h              |  7 +++++++
 security/integrity/ima/ima_modsig.c       | 13 +++++++++++++
 security/integrity/ima/ima_template_lib.c | 15 ++++++++++++++-
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 40a6ddfdd9ea..55f8ef65cab4 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -318,6 +318,7 @@ int ima_read_collect_modsig(enum ima_hooks func, const void 
*buf,
                            int *xattr_len);
 int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, enum hash_algo *algo,
                        const u8 **hash, u8 *len);
+int ima_modsig_serialize_data(struct evm_ima_xattr_data **data, int *data_len);
 void ima_free_xattr_data(struct evm_ima_xattr_data *hdr);
 #else
 static inline bool ima_hook_supports_modsig(enum ima_hooks func)
@@ -340,6 +341,12 @@ static inline int ima_get_modsig_hash(struct 
evm_ima_xattr_data *hdr,
        return -EOPNOTSUPP;
 }
 
+static inline int ima_modsig_serialize_data(struct evm_ima_xattr_data **data,
+                                           int *data_len)
+{
+       return -EOPNOTSUPP;
+}
+
 static inline void ima_free_xattr_data(struct evm_ima_xattr_data *hdr)
 {
        kfree(hdr);
diff --git a/security/integrity/ima/ima_modsig.c 
b/security/integrity/ima/ima_modsig.c
index 587b79a9afef..0424f844c4c3 100644
--- a/security/integrity/ima/ima_modsig.c
+++ b/security/integrity/ima/ima_modsig.c
@@ -190,6 +190,19 @@ int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, 
enum hash_algo *algo,
        return pkcs7_get_digest(modsig->pkcs7_msg, hash, len);
 }
 
+int ima_modsig_serialize_data(struct evm_ima_xattr_data **data, int *data_len)
+{
+       struct modsig_hdr *modsig = (struct modsig_hdr *) *data;
+
+       if (!*data || (*data)->type != IMA_MODSIG)
+               return -EINVAL;
+
+       *data = &modsig->raw_pkcs7;
+       *data_len = modsig->raw_pkcs7_len;
+
+       return 0;
+}
+
 int ima_modsig_verify(struct key *keyring, const void *hdr)
 {
        const struct modsig_hdr *modsig = (const struct modsig_hdr *) hdr;
diff --git a/security/integrity/ima/ima_template_lib.c 
b/security/integrity/ima/ima_template_lib.c
index 36d175816894..417cd153ba60 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -411,10 +411,23 @@ int ima_eventsig_init(struct ima_event_data *event_data,
                      struct ima_field_data *field_data)
 {
        struct evm_ima_xattr_data *xattr_value = event_data->xattr_value;
+       int xattr_len = event_data->xattr_len;
 
        if (!is_signed(xattr_value))
                return 0;
 
-       return ima_write_template_field_data(xattr_value, event_data->xattr_len,
+       /*
+        * The xattr_value for IMA_MODSIG is a runtime structure containing
+        * pointers. Get its raw data instead.
+        */
+       if (xattr_value->type == IMA_MODSIG) {
+               int rc;
+
+               rc = ima_modsig_serialize_data(&xattr_value, &xattr_len);
+               if (rc)
+                       return rc;
+       }
+
+       return ima_write_template_field_data(xattr_value, xattr_len,
                                             DATA_FMT_HEX, field_data);
 }

Reply via email to