ima: restore the original behavior for sending data with ima template
authorRoberto Sassu <roberto.sassu@polito.it>
Mon, 3 Feb 2014 12:56:04 +0000 (13:56 +0100)
committerMimi Zohar <zohar@linux.vnet.ibm.com>
Fri, 7 Mar 2014 16:32:29 +0000 (11:32 -0500)
With the new template mechanism introduced in IMA since kernel 3.13,
the format of data sent through the binary_runtime_measurements interface
is slightly changed. Now, for a generic measurement, the format of
template data (after the template name) is:

template_len | field1_len | field1 | ... | fieldN_len | fieldN

In addition, fields containing a string now include the '\0' termination
character.

Instead, the format for the 'ima' template should be:

SHA1 digest | event name length | event name

It must be noted that while in the IMA 3.13 code 'event name length' is
'IMA_EVENT_NAME_LEN_MAX + 1' (256 bytes), so that the template digest
is calculated correctly, and 'event name' contains '\0', in the pre 3.13
code 'event name length' is exactly the string length and 'event name'
does not contain the termination character.

The patch restores the behavior of the IMA code pre 3.13 for the 'ima'
template so that legacy userspace tools obtain a consistent behavior
when receiving data from the binary_runtime_measurements interface
regardless of which kernel version is used.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Cc: <stable@vger.kernel.org> # 3.3.13: 3ce1217 ima: define template fields library
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
security/integrity/ima/ima.h
security/integrity/ima/ima_fs.c
security/integrity/ima/ima_template_lib.c

index 0356e1d437ca31cde30910567128168dbfd0a5ca..f79fa8be203cd3703ad1a7fedddfe7037f602cdd 100644 (file)
@@ -27,7 +27,7 @@
 #include "../integrity.h"
 
 enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
-                    IMA_SHOW_ASCII };
+                    IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII };
 enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
 
 /* digest size for IMA, fits SHA1 or MD5 */
index db01125926bdb1e696165389bcdd26117e9d25fc..468a3ba3c539941b88cabe9ef7e73fe616be824d 100644 (file)
@@ -160,6 +160,8 @@ static int ima_measurements_show(struct seq_file *m, void *v)
 
                if (is_ima_template && strcmp(field->field_id, "d") == 0)
                        show = IMA_SHOW_BINARY_NO_FIELD_LEN;
+               if (is_ima_template && strcmp(field->field_id, "n") == 0)
+                       show = IMA_SHOW_BINARY_OLD_STRING_FMT;
                field->field_show(m, show, &e->template_data[i]);
        }
        return 0;
index 1683bbf289a407048daad7d4c73154fdb05cfec6..e8592e7bfc2137e1c9f1a83eedba5abf1080b88d 100644 (file)
@@ -109,13 +109,16 @@ static void ima_show_template_data_binary(struct seq_file *m,
                                          enum data_formats datafmt,
                                          struct ima_field_data *field_data)
 {
+       u32 len = (show == IMA_SHOW_BINARY_OLD_STRING_FMT) ?
+           strlen(field_data->data) : field_data->len;
+
        if (show != IMA_SHOW_BINARY_NO_FIELD_LEN)
-               ima_putc(m, &field_data->len, sizeof(u32));
+               ima_putc(m, &len, sizeof(len));
 
-       if (!field_data->len)
+       if (!len)
                return;
 
-       ima_putc(m, field_data->data, field_data->len);
+       ima_putc(m, field_data->data, len);
 }
 
 static void ima_show_template_field_data(struct seq_file *m,
@@ -129,6 +132,7 @@ static void ima_show_template_field_data(struct seq_file *m,
                break;
        case IMA_SHOW_BINARY:
        case IMA_SHOW_BINARY_NO_FIELD_LEN:
+       case IMA_SHOW_BINARY_OLD_STRING_FMT:
                ima_show_template_data_binary(m, show, datafmt, field_data);
                break;
        default: