2019-06-01 02:08:55 -06:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
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 04:16:29 -06:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2013 Politecnico di Torino, Italy
|
|
|
|
* TORSEC group -- http://security.polito.it
|
|
|
|
*
|
|
|
|
* Author: Roberto Sassu <roberto.sassu@polito.it>
|
|
|
|
*
|
|
|
|
* File: ima_template.c
|
|
|
|
* Helpers to manage template descriptors.
|
|
|
|
*/
|
2014-02-24 14:59:56 -07:00
|
|
|
|
2016-12-19 17:22:51 -07:00
|
|
|
#include <linux/rculist.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 04:16:29 -06:00
|
|
|
#include "ima.h"
|
2013-06-07 04:16:30 -06:00
|
|
|
#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 04:16:29 -06:00
|
|
|
|
2017-05-16 06:53:42 -06:00
|
|
|
enum header_fields { HDR_PCR, HDR_DIGEST, HDR_TEMPLATE_NAME,
|
|
|
|
HDR_TEMPLATE_DATA, HDR__LAST };
|
|
|
|
|
2016-12-19 17:22:51 -07:00
|
|
|
static struct ima_template_desc builtin_templates[] = {
|
2013-06-07 04:16:32 -06:00
|
|
|
{.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
|
2014-03-04 09:04:20 -07:00
|
|
|
{.name = "ima-ng", .fmt = "d-ng|n-ng"},
|
|
|
|
{.name = "ima-sig", .fmt = "d-ng|n-ng|sig"},
|
2019-06-24 00:23:30 -06:00
|
|
|
{.name = "ima-buf", .fmt = "d-ng|n-ng|buf"},
|
2019-06-27 20:19:32 -06:00
|
|
|
{.name = "ima-modsig", .fmt = "d-ng|n-ng|sig|d-modsig|modsig"},
|
2014-10-13 06:08:42 -06:00
|
|
|
{.name = "", .fmt = ""}, /* placeholder for a custom format */
|
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 04:16:29 -06:00
|
|
|
};
|
|
|
|
|
2016-12-19 17:22:51 -07:00
|
|
|
static LIST_HEAD(defined_templates);
|
|
|
|
static DEFINE_SPINLOCK(template_list);
|
|
|
|
|
2018-09-07 14:22:23 -06:00
|
|
|
static const struct ima_template_field supported_fields[] = {
|
2014-03-04 09:04:20 -07:00
|
|
|
{.field_id = "d", .field_init = ima_eventdigest_init,
|
2013-06-07 04:16:30 -06:00
|
|
|
.field_show = ima_show_template_digest},
|
2014-03-04 09:04:20 -07:00
|
|
|
{.field_id = "n", .field_init = ima_eventname_init,
|
2013-06-07 04:16:30 -06:00
|
|
|
.field_show = ima_show_template_string},
|
2014-03-04 09:04:20 -07:00
|
|
|
{.field_id = "d-ng", .field_init = ima_eventdigest_ng_init,
|
2013-06-07 04:16:32 -06:00
|
|
|
.field_show = ima_show_template_digest_ng},
|
2014-03-04 09:04:20 -07:00
|
|
|
{.field_id = "n-ng", .field_init = ima_eventname_ng_init,
|
2013-06-07 04:16:32 -06:00
|
|
|
.field_show = ima_show_template_string},
|
2014-03-04 09:04:20 -07:00
|
|
|
{.field_id = "sig", .field_init = ima_eventsig_init,
|
2013-07-23 09:15:00 -06:00
|
|
|
.field_show = ima_show_template_sig},
|
2019-06-24 00:23:30 -06:00
|
|
|
{.field_id = "buf", .field_init = ima_eventbuf_init,
|
|
|
|
.field_show = ima_show_template_buf},
|
2019-06-27 20:19:32 -06:00
|
|
|
{.field_id = "d-modsig", .field_init = ima_eventdigest_modsig_init,
|
|
|
|
.field_show = ima_show_template_digest_ng},
|
|
|
|
{.field_id = "modsig", .field_init = ima_eventmodsig_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 04:16:29 -06:00
|
|
|
};
|
2019-06-27 17:25:46 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Used when restoring measurements carried over from a kexec. 'd' and 'n' don't
|
|
|
|
* need to be accounted for since they shouldn't be defined in the same template
|
|
|
|
* description as 'd-ng' and 'n-ng' respectively.
|
|
|
|
*/
|
2019-06-27 20:19:32 -06:00
|
|
|
#define MAX_TEMPLATE_NAME_LEN sizeof("d-ng|n-ng|sig|buf|d-modisg|modsig")
|
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 04:16:29 -06:00
|
|
|
|
2013-06-07 04:16:33 -06:00
|
|
|
static struct ima_template_desc *ima_template;
|
2013-06-07 04:16:35 -06:00
|
|
|
|
2019-06-27 20:19:33 -06:00
|
|
|
/**
|
|
|
|
* ima_template_has_modsig - Check whether template has modsig-related fields.
|
|
|
|
* @ima_template: IMA template to check.
|
|
|
|
*
|
|
|
|
* Tells whether the given template has fields referencing a file's appended
|
|
|
|
* signature.
|
|
|
|
*/
|
|
|
|
bool ima_template_has_modsig(const struct ima_template_desc *ima_template)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ima_template->num_fields; i++)
|
|
|
|
if (!strcmp(ima_template->fields[i]->field_id, "modsig") ||
|
|
|
|
!strcmp(ima_template->fields[i]->field_id, "d-modsig"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-06-07 04:16:35 -06:00
|
|
|
static int __init ima_template_setup(char *str)
|
|
|
|
{
|
|
|
|
struct ima_template_desc *template_desc;
|
|
|
|
int template_len = strlen(str);
|
|
|
|
|
2014-10-13 06:08:42 -06:00
|
|
|
if (ima_template)
|
|
|
|
return 1;
|
|
|
|
|
2016-12-19 17:22:51 -07:00
|
|
|
ima_init_template_list();
|
|
|
|
|
2013-06-07 04:16:35 -06:00
|
|
|
/*
|
|
|
|
* Verify that a template with the supplied name exists.
|
|
|
|
* If not, use CONFIG_IMA_DEFAULT_TEMPLATE.
|
|
|
|
*/
|
|
|
|
template_desc = lookup_template_desc(str);
|
2014-10-13 06:08:38 -06:00
|
|
|
if (!template_desc) {
|
|
|
|
pr_err("template %s not found, using %s\n",
|
|
|
|
str, CONFIG_IMA_DEFAULT_TEMPLATE);
|
2013-06-07 04:16:35 -06:00
|
|
|
return 1;
|
2014-10-13 06:08:38 -06:00
|
|
|
}
|
2013-06-07 04:16:35 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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) {
|
2014-02-24 14:59:56 -07:00
|
|
|
pr_err("template does not support hash alg\n");
|
2013-06-07 04:16:35 -06:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ima_template = template_desc;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
__setup("ima_template=", ima_template_setup);
|
2013-06-07 04:16:33 -06:00
|
|
|
|
2014-10-13 06:08:42 -06:00
|
|
|
static int __init ima_template_fmt_setup(char *str)
|
|
|
|
{
|
2016-12-19 17:22:51 -07:00
|
|
|
int num_templates = ARRAY_SIZE(builtin_templates);
|
2014-10-13 06:08:42 -06:00
|
|
|
|
|
|
|
if (ima_template)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (template_desc_init_fields(str, NULL, NULL) < 0) {
|
|
|
|
pr_err("format string '%s' not valid, using template %s\n",
|
|
|
|
str, CONFIG_IMA_DEFAULT_TEMPLATE);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-12-19 17:22:51 -07:00
|
|
|
builtin_templates[num_templates - 1].fmt = str;
|
|
|
|
ima_template = builtin_templates + num_templates - 1;
|
|
|
|
|
2014-10-13 06:08:42 -06:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
__setup("ima_template_fmt=", ima_template_fmt_setup);
|
|
|
|
|
2019-06-19 16:46:11 -06:00
|
|
|
struct ima_template_desc *lookup_template_desc(const char *name)
|
2013-06-07 04:16:33 -06:00
|
|
|
{
|
2016-12-19 17:22:51 -07:00
|
|
|
struct ima_template_desc *template_desc;
|
|
|
|
int found = 0;
|
|
|
|
|
|
|
|
rcu_read_lock();
|
|
|
|
list_for_each_entry_rcu(template_desc, &defined_templates, list) {
|
|
|
|
if ((strcmp(template_desc->name, name) == 0) ||
|
|
|
|
(strcmp(template_desc->fmt, name) == 0)) {
|
|
|
|
found = 1;
|
|
|
|
break;
|
|
|
|
}
|
2013-06-07 04:16:33 -06:00
|
|
|
}
|
2016-12-19 17:22:51 -07:00
|
|
|
rcu_read_unlock();
|
|
|
|
return found ? template_desc : NULL;
|
2013-06-07 04:16:33 -06:00
|
|
|
}
|
|
|
|
|
2018-09-07 14:22:23 -06:00
|
|
|
static const 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 04:16:29 -06: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-25 12:18:52 -07: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 04:16:29 -06: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;
|
|
|
|
}
|
|
|
|
|
2019-06-19 16:46:11 -06:00
|
|
|
int template_desc_init_fields(const char *template_fmt,
|
|
|
|
const struct ima_template_field ***fields,
|
|
|
|
int *num_fields)
|
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 04:16:29 -06:00
|
|
|
{
|
2014-10-13 06:08:40 -06:00
|
|
|
const char *template_fmt_ptr;
|
2018-09-07 14:22:23 -06:00
|
|
|
const struct ima_template_field *found_fields[IMA_TEMPLATE_NUM_FIELDS_MAX];
|
2016-12-19 17:22:54 -07:00
|
|
|
int template_num_fields;
|
2014-10-13 06:08:41 -06:00
|
|
|
int i, len;
|
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 04:16:29 -06:00
|
|
|
|
2016-12-19 17:22:54 -07:00
|
|
|
if (num_fields && *num_fields > 0) /* already initialized? */
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
template_num_fields = template_fmt_size(template_fmt);
|
|
|
|
|
2014-10-13 06:08:38 -06:00
|
|
|
if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) {
|
|
|
|
pr_err("format string '%s' contains too many fields\n",
|
|
|
|
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 04:16:29 -06:00
|
|
|
return -EINVAL;
|
2014-10-13 06:08:38 -06:00
|
|
|
}
|
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 04:16:29 -06:00
|
|
|
|
2014-10-13 06:08:40 -06:00
|
|
|
for (i = 0, template_fmt_ptr = template_fmt; i < template_num_fields;
|
|
|
|
i++, template_fmt_ptr += len + 1) {
|
|
|
|
char tmp_field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN + 1];
|
|
|
|
|
|
|
|
len = strchrnul(template_fmt_ptr, '|') - template_fmt_ptr;
|
|
|
|
if (len == 0 || len > IMA_TEMPLATE_FIELD_ID_MAX_LEN) {
|
|
|
|
pr_err("Invalid field with length %d\n", len);
|
2014-10-13 06:08:41 -06:00
|
|
|
return -EINVAL;
|
2014-10-13 06:08:40 -06:00
|
|
|
}
|
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 04:16:29 -06:00
|
|
|
|
2014-10-13 06:08:40 -06:00
|
|
|
memcpy(tmp_field_id, template_fmt_ptr, len);
|
|
|
|
tmp_field_id[len] = '\0';
|
2014-10-13 06:08:41 -06:00
|
|
|
found_fields[i] = lookup_template_field(tmp_field_id);
|
|
|
|
if (!found_fields[i]) {
|
2014-10-13 06:08:40 -06:00
|
|
|
pr_err("field '%s' not found\n", tmp_field_id);
|
2014-10-13 06:08:41 -06:00
|
|
|
return -ENOENT;
|
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 04:16:29 -06:00
|
|
|
}
|
|
|
|
}
|
2014-10-13 06:08:41 -06:00
|
|
|
|
2014-10-13 06:08:42 -06:00
|
|
|
if (fields && num_fields) {
|
|
|
|
*fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL);
|
|
|
|
if (*fields == NULL)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
memcpy(*fields, found_fields, i * sizeof(*fields));
|
|
|
|
*num_fields = i;
|
|
|
|
}
|
2014-10-13 06:08:41 -06:00
|
|
|
|
|
|
|
return 0;
|
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 04:16:29 -06:00
|
|
|
}
|
|
|
|
|
2016-12-19 17:22:51 -07:00
|
|
|
void ima_init_template_list(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!list_empty(&defined_templates))
|
|
|
|
return;
|
|
|
|
|
|
|
|
spin_lock(&template_list);
|
|
|
|
for (i = 0; i < ARRAY_SIZE(builtin_templates); i++) {
|
|
|
|
list_add_tail_rcu(&builtin_templates[i].list,
|
|
|
|
&defined_templates);
|
|
|
|
}
|
|
|
|
spin_unlock(&template_list);
|
|
|
|
}
|
|
|
|
|
2013-06-07 04:16:33 -06:00
|
|
|
struct ima_template_desc *ima_template_desc_current(void)
|
|
|
|
{
|
2016-12-19 17:22:51 -07:00
|
|
|
if (!ima_template) {
|
|
|
|
ima_init_template_list();
|
2013-06-07 04:16:34 -06:00
|
|
|
ima_template =
|
|
|
|
lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE);
|
2016-12-19 17:22:51 -07:00
|
|
|
}
|
2013-06-07 04:16:33 -06:00
|
|
|
return ima_template;
|
|
|
|
}
|
|
|
|
|
2014-09-03 01:19:58 -06:00
|
|
|
int __init ima_init_template(void)
|
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 04:16:29 -06:00
|
|
|
{
|
2014-05-08 02:23:53 -06:00
|
|
|
struct ima_template_desc *template = ima_template_desc_current();
|
2014-10-13 06:08:38 -06:00
|
|
|
int result;
|
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 04:16:29 -06:00
|
|
|
|
2014-10-13 06:08:38 -06:00
|
|
|
result = template_desc_init_fields(template->fmt,
|
|
|
|
&(template->fields),
|
|
|
|
&(template->num_fields));
|
|
|
|
if (result < 0)
|
2014-10-13 06:08:39 -06:00
|
|
|
pr_err("template %s init failed, result: %d\n",
|
|
|
|
(strlen(template->name) ?
|
|
|
|
template->name : template->fmt), result);
|
2014-10-13 06:08:38 -06:00
|
|
|
|
|
|
|
return result;
|
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 04:16:29 -06:00
|
|
|
}
|
2016-12-19 17:22:35 -07:00
|
|
|
|
2016-12-19 17:22:54 -07:00
|
|
|
static struct ima_template_desc *restore_template_fmt(char *template_name)
|
|
|
|
{
|
|
|
|
struct ima_template_desc *template_desc = NULL;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = template_desc_init_fields(template_name, NULL, NULL);
|
|
|
|
if (ret < 0) {
|
|
|
|
pr_err("attempting to initialize the template \"%s\" failed\n",
|
|
|
|
template_name);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
template_desc = kzalloc(sizeof(*template_desc), GFP_KERNEL);
|
|
|
|
if (!template_desc)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
template_desc->name = "";
|
|
|
|
template_desc->fmt = kstrdup(template_name, GFP_KERNEL);
|
|
|
|
if (!template_desc->fmt)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
spin_lock(&template_list);
|
|
|
|
list_add_tail_rcu(&template_desc->list, &defined_templates);
|
|
|
|
spin_unlock(&template_list);
|
|
|
|
out:
|
|
|
|
return template_desc;
|
|
|
|
}
|
|
|
|
|
2016-12-19 17:22:35 -07:00
|
|
|
static int ima_restore_template_data(struct ima_template_desc *template_desc,
|
|
|
|
void *template_data,
|
|
|
|
int template_data_size,
|
|
|
|
struct ima_template_entry **entry)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
int i;
|
|
|
|
|
2019-05-29 10:53:43 -06:00
|
|
|
*entry = kzalloc(struct_size(*entry, template_data,
|
|
|
|
template_desc->num_fields), GFP_NOFS);
|
2016-12-19 17:22:35 -07:00
|
|
|
if (!*entry)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-05-16 06:53:43 -06:00
|
|
|
ret = ima_parse_buf(template_data, template_data + template_data_size,
|
|
|
|
NULL, template_desc->num_fields,
|
|
|
|
(*entry)->template_data, NULL, NULL,
|
|
|
|
ENFORCE_FIELDS | ENFORCE_BUFEND, "template data");
|
|
|
|
if (ret < 0) {
|
|
|
|
kfree(*entry);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-12-19 17:22:35 -07:00
|
|
|
(*entry)->template_desc = template_desc;
|
|
|
|
for (i = 0; i < template_desc->num_fields; i++) {
|
2017-05-16 06:53:43 -06:00
|
|
|
struct ima_field_data *field_data = &(*entry)->template_data[i];
|
|
|
|
u8 *data = field_data->data;
|
2016-12-19 17:22:35 -07:00
|
|
|
|
|
|
|
(*entry)->template_data[i].data =
|
|
|
|
kzalloc(field_data->len + 1, GFP_KERNEL);
|
|
|
|
if (!(*entry)->template_data[i].data) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
break;
|
|
|
|
}
|
2017-05-16 06:53:43 -06:00
|
|
|
memcpy((*entry)->template_data[i].data, data, field_data->len);
|
|
|
|
(*entry)->template_data_len += sizeof(field_data->len);
|
2016-12-19 17:22:35 -07:00
|
|
|
(*entry)->template_data_len += field_data->len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret < 0) {
|
|
|
|
ima_free_template_entry(*entry);
|
|
|
|
*entry = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Restore the serialized binary measurement list without extending PCRs. */
|
|
|
|
int ima_restore_measurement_list(loff_t size, void *buf)
|
|
|
|
{
|
|
|
|
char template_name[MAX_TEMPLATE_NAME_LEN];
|
|
|
|
|
|
|
|
struct ima_kexec_hdr *khdr = buf;
|
2017-05-16 06:53:42 -06:00
|
|
|
struct ima_field_data hdr[HDR__LAST] = {
|
|
|
|
[HDR_PCR] = {.len = sizeof(u32)},
|
|
|
|
[HDR_DIGEST] = {.len = TPM_DIGEST_SIZE},
|
|
|
|
};
|
2016-12-19 17:22:35 -07:00
|
|
|
|
|
|
|
void *bufp = buf + sizeof(*khdr);
|
2016-12-19 17:22:57 -07:00
|
|
|
void *bufendp;
|
2016-12-19 17:22:35 -07:00
|
|
|
struct ima_template_entry *entry;
|
|
|
|
struct ima_template_desc *template_desc;
|
2017-05-16 06:53:42 -06:00
|
|
|
DECLARE_BITMAP(hdr_mask, HDR__LAST);
|
2016-12-19 17:22:35 -07:00
|
|
|
unsigned long count = 0;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (!buf || size < sizeof(*khdr))
|
|
|
|
return 0;
|
|
|
|
|
2016-12-19 17:22:57 -07:00
|
|
|
if (ima_canonical_fmt) {
|
|
|
|
khdr->version = le16_to_cpu(khdr->version);
|
|
|
|
khdr->count = le64_to_cpu(khdr->count);
|
|
|
|
khdr->buffer_size = le64_to_cpu(khdr->buffer_size);
|
|
|
|
}
|
|
|
|
|
2016-12-19 17:22:35 -07:00
|
|
|
if (khdr->version != 1) {
|
|
|
|
pr_err("attempting to restore a incompatible measurement list");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (khdr->count > ULONG_MAX - 1) {
|
|
|
|
pr_err("attempting to restore too many measurements");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2017-05-16 06:53:42 -06:00
|
|
|
bitmap_zero(hdr_mask, HDR__LAST);
|
|
|
|
bitmap_set(hdr_mask, HDR_PCR, 1);
|
|
|
|
bitmap_set(hdr_mask, HDR_DIGEST, 1);
|
|
|
|
|
2016-12-19 17:22:35 -07:00
|
|
|
/*
|
|
|
|
* ima kexec buffer prefix: version, buffer size, count
|
|
|
|
* v1 format: pcr, digest, template-name-len, template-name,
|
|
|
|
* template-data-size, template-data
|
|
|
|
*/
|
2016-12-19 17:22:57 -07:00
|
|
|
bufendp = buf + khdr->buffer_size;
|
2016-12-19 17:22:35 -07:00
|
|
|
while ((bufp < bufendp) && (count++ < khdr->count)) {
|
2017-05-16 06:53:42 -06:00
|
|
|
int enforce_mask = ENFORCE_FIELDS;
|
2016-12-19 17:22:35 -07:00
|
|
|
|
2017-05-16 06:53:42 -06:00
|
|
|
enforce_mask |= (count == khdr->count) ? ENFORCE_BUFEND : 0;
|
|
|
|
ret = ima_parse_buf(bufp, bufendp, &bufp, HDR__LAST, hdr, NULL,
|
|
|
|
hdr_mask, enforce_mask, "entry header");
|
|
|
|
if (ret < 0)
|
|
|
|
break;
|
2016-12-19 17:22:57 -07:00
|
|
|
|
2017-05-16 06:53:42 -06:00
|
|
|
if (hdr[HDR_TEMPLATE_NAME].len >= MAX_TEMPLATE_NAME_LEN) {
|
2017-11-16 08:27:29 -07:00
|
|
|
pr_err("attempting to restore a template name that is too long\n");
|
2016-12-19 17:22:35 -07:00
|
|
|
ret = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* template name is not null terminated */
|
2017-05-16 06:53:42 -06:00
|
|
|
memcpy(template_name, hdr[HDR_TEMPLATE_NAME].data,
|
|
|
|
hdr[HDR_TEMPLATE_NAME].len);
|
|
|
|
template_name[hdr[HDR_TEMPLATE_NAME].len] = 0;
|
2016-12-19 17:22:35 -07:00
|
|
|
|
|
|
|
if (strcmp(template_name, "ima") == 0) {
|
2017-11-16 08:27:29 -07:00
|
|
|
pr_err("attempting to restore an unsupported template \"%s\" failed\n",
|
|
|
|
template_name);
|
2016-12-19 17:22:35 -07:00
|
|
|
ret = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
template_desc = lookup_template_desc(template_name);
|
|
|
|
if (!template_desc) {
|
2016-12-19 17:22:54 -07:00
|
|
|
template_desc = restore_template_fmt(template_name);
|
|
|
|
if (!template_desc)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Only the running system's template format is initialized
|
|
|
|
* on boot. As needed, initialize the other template formats.
|
|
|
|
*/
|
|
|
|
ret = template_desc_init_fields(template_desc->fmt,
|
|
|
|
&(template_desc->fields),
|
|
|
|
&(template_desc->num_fields));
|
|
|
|
if (ret < 0) {
|
2017-11-16 08:27:29 -07:00
|
|
|
pr_err("attempting to restore the template fmt \"%s\" failed\n",
|
|
|
|
template_desc->fmt);
|
2016-12-19 17:22:35 -07:00
|
|
|
ret = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ima_restore_template_data(template_desc,
|
2017-05-16 06:53:42 -06:00
|
|
|
hdr[HDR_TEMPLATE_DATA].data,
|
|
|
|
hdr[HDR_TEMPLATE_DATA].len,
|
2016-12-19 17:22:35 -07:00
|
|
|
&entry);
|
|
|
|
if (ret < 0)
|
|
|
|
break;
|
|
|
|
|
2017-05-16 06:53:42 -06:00
|
|
|
memcpy(entry->digest, hdr[HDR_DIGEST].data,
|
|
|
|
hdr[HDR_DIGEST].len);
|
|
|
|
entry->pcr = !ima_canonical_fmt ? *(hdr[HDR_PCR].data) :
|
|
|
|
le32_to_cpu(*(hdr[HDR_PCR].data));
|
2016-12-19 17:22:35 -07:00
|
|
|
ret = ima_restore_measurement_entry(entry);
|
|
|
|
if (ret < 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|