linux/security/integrity/ima/ima_template.c

188 lines
4.5 KiB
C
Raw Normal View History

ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
/*
* Copyright (C) 2013 Politecnico di Torino, Italy
* TORSEC group -- http://security.polito.it
*
* Author: Roberto Sassu <roberto.sassu@polito.it>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*
* File: ima_template.c
* Helpers to manage template descriptors.
*/
#include <crypto/hash_info.h>
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
#include "ima.h"
#include "ima_template_lib.h"
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
static struct ima_template_desc defined_templates[] = {
{.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
{.name = "ima-ng",.fmt = "d-ng|n-ng"},
{.name = "ima-sig",.fmt = "d-ng|n-ng|sig"},
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
};
static struct ima_template_field supported_fields[] = {
{.field_id = "d",.field_init = ima_eventdigest_init,
.field_show = ima_show_template_digest},
{.field_id = "n",.field_init = ima_eventname_init,
.field_show = ima_show_template_string},
{.field_id = "d-ng",.field_init = ima_eventdigest_ng_init,
.field_show = ima_show_template_digest_ng},
{.field_id = "n-ng",.field_init = ima_eventname_ng_init,
.field_show = ima_show_template_string},
{.field_id = "sig",.field_init = ima_eventsig_init,
.field_show = ima_show_template_sig},
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
};
static struct ima_template_desc *ima_template;
static struct ima_template_desc *lookup_template_desc(const char *name);
static int __init ima_template_setup(char *str)
{
struct ima_template_desc *template_desc;
int template_len = strlen(str);
/*
* Verify that a template with the supplied name exists.
* If not, use CONFIG_IMA_DEFAULT_TEMPLATE.
*/
template_desc = lookup_template_desc(str);
if (!template_desc)
return 1;
/*
* Verify whether the current hash algorithm is supported
* by the 'ima' template.
*/
if (template_len == 3 && strcmp(str, IMA_TEMPLATE_IMA_NAME) == 0 &&
ima_hash_algo != HASH_ALGO_SHA1 && ima_hash_algo != HASH_ALGO_MD5) {
pr_err("IMA: template does not support hash alg\n");
return 1;
}
ima_template = template_desc;
return 1;
}
__setup("ima_template=", ima_template_setup);
static struct ima_template_desc *lookup_template_desc(const char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(defined_templates); i++) {
if (strcmp(defined_templates[i].name, name) == 0)
return defined_templates + i;
}
return NULL;
}
static struct ima_template_field *lookup_template_field(const char *field_id)
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
{
int i;
for (i = 0; i < ARRAY_SIZE(supported_fields); i++)
if (strncmp(supported_fields[i].field_id, field_id,
IMA_TEMPLATE_FIELD_ID_MAX_LEN) == 0)
return &supported_fields[i];
return NULL;
}
ima: make a copy of template_fmt in template_desc_init_fields() This patch makes a copy of the 'template_fmt' function argument so that the latter will not be modified by strsep(), which does the splitting by replacing the given separator with '\0'.  IMA: No TPM chip found, activating TPM-bypass!  Unable to handle kernel pointer dereference at virtual kernel address 0000000000842000  Oops: 0004 [#1] SMP  Modules linked in:  CPU: 3 PID: 1 Comm: swapper/0 Not tainted 3.12.0-rc2-00098-g3ce1217d6cd5 #17  task: 000000003ffa0000 ti: 000000003ff84000 task.ti: 000000003ff84000  Krnl PSW : 0704e00180000000 000000000044bf88 (strsep+0x7c/0xa0)             R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 EA:3  Krnl GPRS: 000000000000007c 000000000000007c 000000003ff87d90 0000000000821fd8             0000000000000000 000000000000007c 0000000000aa37e0 0000000000aa9008             0000000000000051 0000000000a114d8 0000000100000002 0000000000842bde             0000000000842bdf 00000000006f97f0 000000000040062c 000000003ff87cf0  Krnl Code: 000000000044bf7c: a7f4000a           brc     15,44bf90             000000000044bf80: b90200cc           ltgr    %r12,%r12            #000000000044bf84: a7840006           brc     8,44bf90            >000000000044bf88: 9200c000           mvi     0(%r12),0             000000000044bf8c: 41c0c001           la      %r12,1(%r12)             000000000044bf90: e3c020000024       stg     %r12,0(%r2)             000000000044bf96: b904002b           lgr     %r2,%r11             000000000044bf9a: ebbcf0700004       lmg     %r11,%r12,112(%r15)  Call Trace:  ([<00000000004005fe>] ima_init_template+0xa2/0x1bc)   [<0000000000a7c896>] ima_init+0x7a/0xa8   [<0000000000a7c938>] init_ima+0x24/0x40   [<00000000001000e8>] do_one_initcall+0x68/0x128   [<0000000000a4eb56>] kernel_init_freeable+0x20a/0x2b4   [<00000000006a1ff4>] kernel_init+0x30/0x178   [<00000000006b69fe>] kernel_thread_starter+0x6/0xc   [<00000000006b69f8>] kernel_thread_starter+0x0/0xc  Last Breaking-Event-Address:   [<000000000044bf42>] strsep+0x36/0xa0 Fixes commit: adf53a7 ima: new templates management mechanism Changelog v1: - make template_fmt 'const char *' (reported-by James Morris) - fix kstrdup memory leak (reported-by James Morris) Reported-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Tested-by: Heiko Carstens <heiko.carstens@de.ibm.com>
2013-11-26 03:18:52 +08:00
static int template_fmt_size(const char *template_fmt)
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
{
char c;
int template_fmt_len = strlen(template_fmt);
int i = 0, j = 0;
while (i < template_fmt_len) {
c = template_fmt[i];
if (c == '|')
j++;
i++;
}
return j + 1;
}
ima: make a copy of template_fmt in template_desc_init_fields() This patch makes a copy of the 'template_fmt' function argument so that the latter will not be modified by strsep(), which does the splitting by replacing the given separator with '\0'.  IMA: No TPM chip found, activating TPM-bypass!  Unable to handle kernel pointer dereference at virtual kernel address 0000000000842000  Oops: 0004 [#1] SMP  Modules linked in:  CPU: 3 PID: 1 Comm: swapper/0 Not tainted 3.12.0-rc2-00098-g3ce1217d6cd5 #17  task: 000000003ffa0000 ti: 000000003ff84000 task.ti: 000000003ff84000  Krnl PSW : 0704e00180000000 000000000044bf88 (strsep+0x7c/0xa0)             R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 EA:3  Krnl GPRS: 000000000000007c 000000000000007c 000000003ff87d90 0000000000821fd8             0000000000000000 000000000000007c 0000000000aa37e0 0000000000aa9008             0000000000000051 0000000000a114d8 0000000100000002 0000000000842bde             0000000000842bdf 00000000006f97f0 000000000040062c 000000003ff87cf0  Krnl Code: 000000000044bf7c: a7f4000a           brc     15,44bf90             000000000044bf80: b90200cc           ltgr    %r12,%r12            #000000000044bf84: a7840006           brc     8,44bf90            >000000000044bf88: 9200c000           mvi     0(%r12),0             000000000044bf8c: 41c0c001           la      %r12,1(%r12)             000000000044bf90: e3c020000024       stg     %r12,0(%r2)             000000000044bf96: b904002b           lgr     %r2,%r11             000000000044bf9a: ebbcf0700004       lmg     %r11,%r12,112(%r15)  Call Trace:  ([<00000000004005fe>] ima_init_template+0xa2/0x1bc)   [<0000000000a7c896>] ima_init+0x7a/0xa8   [<0000000000a7c938>] init_ima+0x24/0x40   [<00000000001000e8>] do_one_initcall+0x68/0x128   [<0000000000a4eb56>] kernel_init_freeable+0x20a/0x2b4   [<00000000006a1ff4>] kernel_init+0x30/0x178   [<00000000006b69fe>] kernel_thread_starter+0x6/0xc   [<00000000006b69f8>] kernel_thread_starter+0x0/0xc  Last Breaking-Event-Address:   [<000000000044bf42>] strsep+0x36/0xa0 Fixes commit: adf53a7 ima: new templates management mechanism Changelog v1: - make template_fmt 'const char *' (reported-by James Morris) - fix kstrdup memory leak (reported-by James Morris) Reported-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Tested-by: Heiko Carstens <heiko.carstens@de.ibm.com>
2013-11-26 03:18:52 +08:00
static int template_desc_init_fields(const char *template_fmt,
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
struct ima_template_field ***fields,
int *num_fields)
{
char *c, *template_fmt_copy, *template_fmt_ptr;
int template_num_fields = template_fmt_size(template_fmt);
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
int i, result = 0;
if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX)
return -EINVAL;
ima: make a copy of template_fmt in template_desc_init_fields() This patch makes a copy of the 'template_fmt' function argument so that the latter will not be modified by strsep(), which does the splitting by replacing the given separator with '\0'.  IMA: No TPM chip found, activating TPM-bypass!  Unable to handle kernel pointer dereference at virtual kernel address 0000000000842000  Oops: 0004 [#1] SMP  Modules linked in:  CPU: 3 PID: 1 Comm: swapper/0 Not tainted 3.12.0-rc2-00098-g3ce1217d6cd5 #17  task: 000000003ffa0000 ti: 000000003ff84000 task.ti: 000000003ff84000  Krnl PSW : 0704e00180000000 000000000044bf88 (strsep+0x7c/0xa0)             R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 EA:3  Krnl GPRS: 000000000000007c 000000000000007c 000000003ff87d90 0000000000821fd8             0000000000000000 000000000000007c 0000000000aa37e0 0000000000aa9008             0000000000000051 0000000000a114d8 0000000100000002 0000000000842bde             0000000000842bdf 00000000006f97f0 000000000040062c 000000003ff87cf0  Krnl Code: 000000000044bf7c: a7f4000a           brc     15,44bf90             000000000044bf80: b90200cc           ltgr    %r12,%r12            #000000000044bf84: a7840006           brc     8,44bf90            >000000000044bf88: 9200c000           mvi     0(%r12),0             000000000044bf8c: 41c0c001           la      %r12,1(%r12)             000000000044bf90: e3c020000024       stg     %r12,0(%r2)             000000000044bf96: b904002b           lgr     %r2,%r11             000000000044bf9a: ebbcf0700004       lmg     %r11,%r12,112(%r15)  Call Trace:  ([<00000000004005fe>] ima_init_template+0xa2/0x1bc)   [<0000000000a7c896>] ima_init+0x7a/0xa8   [<0000000000a7c938>] init_ima+0x24/0x40   [<00000000001000e8>] do_one_initcall+0x68/0x128   [<0000000000a4eb56>] kernel_init_freeable+0x20a/0x2b4   [<00000000006a1ff4>] kernel_init+0x30/0x178   [<00000000006b69fe>] kernel_thread_starter+0x6/0xc   [<00000000006b69f8>] kernel_thread_starter+0x0/0xc  Last Breaking-Event-Address:   [<000000000044bf42>] strsep+0x36/0xa0 Fixes commit: adf53a7 ima: new templates management mechanism Changelog v1: - make template_fmt 'const char *' (reported-by James Morris) - fix kstrdup memory leak (reported-by James Morris) Reported-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Tested-by: Heiko Carstens <heiko.carstens@de.ibm.com>
2013-11-26 03:18:52 +08:00
/* copying is needed as strsep() modifies the original buffer */
template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL);
if (template_fmt_copy == NULL)
return -ENOMEM;
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
*fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL);
if (*fields == NULL) {
result = -ENOMEM;
goto out;
}
template_fmt_ptr = template_fmt_copy;
for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL &&
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
i < template_num_fields; i++) {
struct ima_template_field *f = lookup_template_field(c);
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
if (!f) {
result = -ENOENT;
goto out;
}
(*fields)[i] = f;
}
*num_fields = i;
out:
ima: make a copy of template_fmt in template_desc_init_fields() This patch makes a copy of the 'template_fmt' function argument so that the latter will not be modified by strsep(), which does the splitting by replacing the given separator with '\0'.  IMA: No TPM chip found, activating TPM-bypass!  Unable to handle kernel pointer dereference at virtual kernel address 0000000000842000  Oops: 0004 [#1] SMP  Modules linked in:  CPU: 3 PID: 1 Comm: swapper/0 Not tainted 3.12.0-rc2-00098-g3ce1217d6cd5 #17  task: 000000003ffa0000 ti: 000000003ff84000 task.ti: 000000003ff84000  Krnl PSW : 0704e00180000000 000000000044bf88 (strsep+0x7c/0xa0)             R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 EA:3  Krnl GPRS: 000000000000007c 000000000000007c 000000003ff87d90 0000000000821fd8             0000000000000000 000000000000007c 0000000000aa37e0 0000000000aa9008             0000000000000051 0000000000a114d8 0000000100000002 0000000000842bde             0000000000842bdf 00000000006f97f0 000000000040062c 000000003ff87cf0  Krnl Code: 000000000044bf7c: a7f4000a           brc     15,44bf90             000000000044bf80: b90200cc           ltgr    %r12,%r12            #000000000044bf84: a7840006           brc     8,44bf90            >000000000044bf88: 9200c000           mvi     0(%r12),0             000000000044bf8c: 41c0c001           la      %r12,1(%r12)             000000000044bf90: e3c020000024       stg     %r12,0(%r2)             000000000044bf96: b904002b           lgr     %r2,%r11             000000000044bf9a: ebbcf0700004       lmg     %r11,%r12,112(%r15)  Call Trace:  ([<00000000004005fe>] ima_init_template+0xa2/0x1bc)   [<0000000000a7c896>] ima_init+0x7a/0xa8   [<0000000000a7c938>] init_ima+0x24/0x40   [<00000000001000e8>] do_one_initcall+0x68/0x128   [<0000000000a4eb56>] kernel_init_freeable+0x20a/0x2b4   [<00000000006a1ff4>] kernel_init+0x30/0x178   [<00000000006b69fe>] kernel_thread_starter+0x6/0xc   [<00000000006b69f8>] kernel_thread_starter+0x0/0xc  Last Breaking-Event-Address:   [<000000000044bf42>] strsep+0x36/0xa0 Fixes commit: adf53a7 ima: new templates management mechanism Changelog v1: - make template_fmt 'const char *' (reported-by James Morris) - fix kstrdup memory leak (reported-by James Morris) Reported-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Tested-by: Heiko Carstens <heiko.carstens@de.ibm.com>
2013-11-26 03:18:52 +08:00
if (result < 0) {
kfree(*fields);
*fields = NULL;
}
kfree(template_fmt_copy);
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
return result;
}
static int init_defined_templates(void)
{
int i = 0;
int result = 0;
/* Init defined templates. */
for (i = 0; i < ARRAY_SIZE(defined_templates); i++) {
struct ima_template_desc *template = &defined_templates[i];
result = template_desc_init_fields(template->fmt,
&(template->fields),
&(template->num_fields));
if (result < 0)
return result;
}
return result;
}
struct ima_template_desc *ima_template_desc_current(void)
{
if (!ima_template)
ima_template =
lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE);
return ima_template;
}
ima: new templates management mechanism The original 'ima' template is fixed length, containing the filedata hash and pathname. The filedata hash is limited to 20 bytes (md5/sha1). The pathname is a null terminated string, limited to 255 characters. To overcome these limitations and to add additional file metadata, it is necessary to extend the current version of IMA by defining additional templates. The main reason to introduce this feature is that, each time a new template is defined, the functions that generate and display the measurement list would include the code for handling a new format and, thus, would significantly grow over time. This patch set solves this problem by separating the template management from the remaining IMA code. The core of this solution is the definition of two new data structures: a template descriptor, to determine which information should be included in the measurement list, and a template field, to generate and display data of a given type. To define a new template field, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Initially, this patch set defines the following template fields (support for additional data types will be added later):  - 'd': the digest of the event (i.e. the digest of a measured file),         calculated with the SHA1 or MD5 hash algorithm;  - 'n': the name of the event (i.e. the file name), with size up to         255 bytes;  - 'd-ng': the digest of the event, calculated with an arbitrary hash            algorithm (field format: [<hash algo>:]digest, where the digest            prefix is shown only if the hash algorithm is not SHA1 or MD5);  - 'n-ng': the name of the event, without size limitations. Defining a new template descriptor requires specifying the template format, a string of field identifiers separated by the '|' character. This patch set defines the following template descriptors:  - "ima": its format is 'd|n';  - "ima-ng" (default): its format is 'd-ng|n-ng' Further details about the new template architecture can be found in Documentation/security/IMA-templates.txt. Changelog: - don't defer calling ima_init_template() - Mimi - don't define ima_lookup_template_desc() until used - Mimi - squashed with documentation patch - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2013-06-07 18:16:29 +08:00
int ima_init_template(void)
{
int result;
result = init_defined_templates();
if (result < 0)
return result;
return 0;
}