ima: Introduce template field evmsig and write to field sig as fallback
authorRoberto Sassu <roberto.sassu@huawei.com>
Fri, 14 May 2021 15:27:52 +0000 (17:27 +0200)
committerMimi Zohar <zohar@linux.ibm.com>
Tue, 1 Jun 2021 16:30:51 +0000 (12:30 -0400)
With the patch to accept EVM portable signatures when the
appraise_type=imasig requirement is specified in the policy, appraisal can
be successfully done even if the file does not have an IMA signature.

However, remote attestation would not see that a different signature type
was used, as only IMA signatures can be included in the measurement list.
This patch solves the issue by introducing the new template field 'evmsig'
to show EVM portable signatures and by including its value in the existing
field 'sig' if the IMA signature is not found.

Suggested-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Documentation/security/IMA-templates.rst
security/integrity/ima/ima_template.c
security/integrity/ima/ima_template_lib.c
security/integrity/ima/ima_template_lib.h

index c5a8432972ef1dfef1c2bbaf996918417de493c3..9f3e86ab028a45cfd0faa81ec4299d483d288070 100644 (file)
@@ -70,9 +70,11 @@ descriptors by adding their identifier to the format string
    prefix is shown only if the hash algorithm is not SHA1 or MD5);
  - 'd-modsig': the digest of the event without the appended modsig;
  - 'n-ng': the name of the event, without size limitations;
- - 'sig': the file signature;
+ - 'sig': the file signature, or the EVM portable signature if the file
+   signature is not found;
  - 'modsig' the appended file signature;
  - 'buf': the buffer data that was used to generate the hash without size limitations;
+ - 'evmsig': the EVM portable signature;
 
 
 Below, there is the list of defined template descriptors:
index 4e081e650047671179ab6649b6c2ce71589d4d62..7a60848c04a54ef71ab1af82886066f91c8b1391 100644 (file)
@@ -45,6 +45,8 @@ static const struct ima_template_field supported_fields[] = {
         .field_show = ima_show_template_digest_ng},
        {.field_id = "modsig", .field_init = ima_eventmodsig_init,
         .field_show = ima_show_template_sig},
+       {.field_id = "evmsig", .field_init = ima_eventevmsig_init,
+        .field_show = ima_show_template_sig},
 };
 
 /*
index c022ee9e2a4e626fe11b63d2b55503295f088fd9..4314d9a3514c18a1775b570ff07e34749b831485 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "ima_template_lib.h"
+#include <linux/xattr.h>
 
 static bool ima_template_hash_algo_allowed(u8 algo)
 {
@@ -438,7 +439,7 @@ int ima_eventsig_init(struct ima_event_data *event_data,
        struct evm_ima_xattr_data *xattr_value = event_data->xattr_value;
 
        if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
-               return 0;
+               return ima_eventevmsig_init(event_data, field_data);
 
        return ima_write_template_field_data(xattr_value, event_data->xattr_len,
                                             DATA_FMT_HEX, field_data);
@@ -484,3 +485,33 @@ int ima_eventmodsig_init(struct ima_event_data *event_data,
        return ima_write_template_field_data(data, data_len, DATA_FMT_HEX,
                                             field_data);
 }
+
+/*
+ *  ima_eventevmsig_init - include the EVM portable signature as part of the
+ *  template data
+ */
+int ima_eventevmsig_init(struct ima_event_data *event_data,
+                        struct ima_field_data *field_data)
+{
+       struct evm_ima_xattr_data *xattr_data = NULL;
+       int rc = 0;
+
+       if (!event_data->file)
+               return 0;
+
+       rc = vfs_getxattr_alloc(&init_user_ns, file_dentry(event_data->file),
+                               XATTR_NAME_EVM, (char **)&xattr_data, 0,
+                               GFP_NOFS);
+       if (rc <= 0)
+               return 0;
+
+       if (xattr_data->type != EVM_XATTR_PORTABLE_DIGSIG) {
+               kfree(xattr_data);
+               return 0;
+       }
+
+       rc = ima_write_template_field_data((char *)xattr_data, rc, DATA_FMT_HEX,
+                                          field_data);
+       kfree(xattr_data);
+       return rc;
+}
index 6b3b880637a0c9baec28be5806ffe29ca7093dd1..f4b2a2056d1d5ed2e876568b5a17af8cd48a8fa3 100644 (file)
@@ -46,4 +46,6 @@ int ima_eventbuf_init(struct ima_event_data *event_data,
                      struct ima_field_data *field_data);
 int ima_eventmodsig_init(struct ima_event_data *event_data,
                         struct ima_field_data *field_data);
+int ima_eventevmsig_init(struct ima_event_data *event_data,
+                        struct ima_field_data *field_data);
 #endif /* __LINUX_IMA_TEMPLATE_LIB_H */