diff options
| author | Roberto Sassu <roberto.sassu@polito.it> | 2014-10-13 08:08:42 -0400 |
|---|---|---|
| committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2014-10-13 08:39:02 -0400 |
| commit | c2426d2ad5027397342107b7ff094aa9b234acb8 (patch) | |
| tree | a94bfc6a99f121a68890388bebbdf8dcc7299ad7 | |
| parent | 1bd7face74391ddfc568b3e638f156da1ed77aa6 (diff) | |
ima: added support for new kernel cmdline parameter ima_template_fmt
This patch allows users to provide a custom template format through the
new kernel command line parameter 'ima_template_fmt'. If the supplied
format is not valid, IMA uses the default template descriptor.
Changelog:
- v3:
- added check for 'fields' and 'num_fields' in
template_desc_init_fields() (suggested by Mimi Zohar)
- v2:
- using template_desc_init_fields() to validate a format string
(Roberto Sassu)
- updated documentation by stating that only the chosen template
descriptor is initialized (Roberto Sassu)
- v1:
- simplified code of ima_template_fmt_setup()
(Roberto Sassu, suggested by Mimi Zohar)
Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
| -rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
| -rw-r--r-- | Documentation/security/IMA-templates.txt | 29 | ||||
| -rw-r--r-- | security/integrity/ima/ima_template.c | 39 |
3 files changed, 52 insertions, 20 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 802a3fd9e485..06b2cd5739dd 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -1318,6 +1318,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
| 1318 | Formats: { "ima" | "ima-ng" } | 1318 | Formats: { "ima" | "ima-ng" } |
| 1319 | Default: "ima-ng" | 1319 | Default: "ima-ng" |
| 1320 | 1320 | ||
| 1321 | ima_template_fmt= | ||
| 1322 | [IMA] Define a custom template format. | ||
| 1323 | Format: { "field1|...|fieldN" } | ||
| 1324 | |||
| 1321 | ima.ahash_minsize= [IMA] Minimum file size for asynchronous hash usage | 1325 | ima.ahash_minsize= [IMA] Minimum file size for asynchronous hash usage |
| 1322 | Format: <min_file_size> | 1326 | Format: <min_file_size> |
| 1323 | Set the minimal file size for using asynchronous hash. | 1327 | Set the minimal file size for using asynchronous hash. |
diff --git a/Documentation/security/IMA-templates.txt b/Documentation/security/IMA-templates.txt index a4e102dddfea..839b5dad9226 100644 --- a/Documentation/security/IMA-templates.txt +++ b/Documentation/security/IMA-templates.txt | |||
| @@ -27,25 +27,22 @@ Managing templates with these structures is very simple. To support | |||
| 27 | a new data type, developers define the field identifier and implement | 27 | a new data type, developers define the field identifier and implement |
| 28 | two functions, init() and show(), respectively to generate and display | 28 | two functions, init() and show(), respectively to generate and display |
| 29 | measurement entries. Defining a new template descriptor requires | 29 | measurement entries. Defining a new template descriptor requires |
| 30 | specifying the template format, a string of field identifiers separated | 30 | specifying the template format (a string of field identifiers separated |
| 31 | by the '|' character. While in the current implementation it is possible | 31 | by the '|' character) through the 'ima_template_fmt' kernel command line |
| 32 | to define new template descriptors only by adding their definition in the | 32 | parameter. At boot time, IMA initializes the chosen template descriptor |
| 33 | template specific code (ima_template.c), in a future version it will be | 33 | by translating the format into an array of template fields structures taken |
| 34 | possible to register a new template on a running kernel by supplying to IMA | 34 | from the set of the supported ones. |
| 35 | the desired format string. In this version, IMA initializes at boot time | ||
| 36 | all defined template descriptors by translating the format into an array | ||
| 37 | of template fields structures taken from the set of the supported ones. | ||
| 38 | 35 | ||
| 39 | After the initialization step, IMA will call ima_alloc_init_template() | 36 | After the initialization step, IMA will call ima_alloc_init_template() |
| 40 | (new function defined within the patches for the new template management | 37 | (new function defined within the patches for the new template management |
| 41 | mechanism) to generate a new measurement entry by using the template | 38 | mechanism) to generate a new measurement entry by using the template |
| 42 | descriptor chosen through the kernel configuration or through the newly | 39 | descriptor chosen through the kernel configuration or through the newly |
| 43 | introduced 'ima_template=' kernel command line parameter. It is during this | 40 | introduced 'ima_template' and 'ima_template_fmt' kernel command line parameters. |
| 44 | phase that the advantages of the new architecture are clearly shown: | 41 | It is during this phase that the advantages of the new architecture are |
| 45 | the latter function will not contain specific code to handle a given template | 42 | clearly shown: the latter function will not contain specific code to handle |
| 46 | but, instead, it simply calls the init() method of the template fields | 43 | a given template but, instead, it simply calls the init() method of the template |
| 47 | associated to the chosen template descriptor and store the result (pointer | 44 | fields associated to the chosen template descriptor and store the result |
| 48 | to allocated data and data length) in the measurement entry structure. | 45 | (pointer to allocated data and data length) in the measurement entry structure. |
| 49 | 46 | ||
| 50 | The same mechanism is employed to display measurements entries. | 47 | The same mechanism is employed to display measurements entries. |
| 51 | The functions ima[_ascii]_measurements_show() retrieve, for each entry, | 48 | The functions ima[_ascii]_measurements_show() retrieve, for each entry, |
| @@ -86,4 +83,6 @@ currently the following methods are supported: | |||
| 86 | - select a template descriptor among those supported in the kernel | 83 | - select a template descriptor among those supported in the kernel |
| 87 | configuration ('ima-ng' is the default choice); | 84 | configuration ('ima-ng' is the default choice); |
| 88 | - specify a template descriptor name from the kernel command line through | 85 | - specify a template descriptor name from the kernel command line through |
| 89 | the 'ima_template=' parameter. | 86 | the 'ima_template=' parameter; |
| 87 | - register a new template descriptor with custom format through the kernel | ||
| 88 | command line parameter 'ima_template_fmt='. | ||
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index 65117ba06809..0b7404ebfa80 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c | |||
| @@ -24,6 +24,7 @@ static struct ima_template_desc defined_templates[] = { | |||
| 24 | {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT}, | 24 | {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT}, |
| 25 | {.name = "ima-ng", .fmt = "d-ng|n-ng"}, | 25 | {.name = "ima-ng", .fmt = "d-ng|n-ng"}, |
| 26 | {.name = "ima-sig", .fmt = "d-ng|n-ng|sig"}, | 26 | {.name = "ima-sig", .fmt = "d-ng|n-ng|sig"}, |
| 27 | {.name = "", .fmt = ""}, /* placeholder for a custom format */ | ||
| 27 | }; | 28 | }; |
| 28 | 29 | ||
| 29 | static struct ima_template_field supported_fields[] = { | 30 | static struct ima_template_field supported_fields[] = { |
| @@ -41,12 +42,18 @@ static struct ima_template_field supported_fields[] = { | |||
| 41 | 42 | ||
| 42 | static struct ima_template_desc *ima_template; | 43 | static struct ima_template_desc *ima_template; |
| 43 | static struct ima_template_desc *lookup_template_desc(const char *name); | 44 | static struct ima_template_desc *lookup_template_desc(const char *name); |
| 45 | static int template_desc_init_fields(const char *template_fmt, | ||
| 46 | struct ima_template_field ***fields, | ||
| 47 | int *num_fields); | ||
| 44 | 48 | ||
| 45 | static int __init ima_template_setup(char *str) | 49 | static int __init ima_template_setup(char *str) |
| 46 | { | 50 | { |
| 47 | struct ima_template_desc *template_desc; | 51 | struct ima_template_desc *template_desc; |
| 48 | int template_len = strlen(str); | 52 | int template_len = strlen(str); |
| 49 | 53 | ||
| 54 | if (ima_template) | ||
| 55 | return 1; | ||
| 56 | |||
| 50 | /* | 57 | /* |
| 51 | * Verify that a template with the supplied name exists. | 58 | * Verify that a template with the supplied name exists. |
| 52 | * If not, use CONFIG_IMA_DEFAULT_TEMPLATE. | 59 | * If not, use CONFIG_IMA_DEFAULT_TEMPLATE. |
| @@ -73,6 +80,25 @@ static int __init ima_template_setup(char *str) | |||
| 73 | } | 80 | } |
| 74 | __setup("ima_template=", ima_template_setup); | 81 | __setup("ima_template=", ima_template_setup); |
| 75 | 82 | ||
| 83 | static int __init ima_template_fmt_setup(char *str) | ||
| 84 | { | ||
| 85 | int num_templates = ARRAY_SIZE(defined_templates); | ||
| 86 | |||
| 87 | if (ima_template) | ||
| 88 | return 1; | ||
| 89 | |||
| 90 | if (template_desc_init_fields(str, NULL, NULL) < 0) { | ||
| 91 | pr_err("format string '%s' not valid, using template %s\n", | ||
| 92 | str, CONFIG_IMA_DEFAULT_TEMPLATE); | ||
| 93 | return 1; | ||
| 94 | } | ||
| 95 | |||
| 96 | defined_templates[num_templates - 1].fmt = str; | ||
| 97 | ima_template = defined_templates + num_templates - 1; | ||
| 98 | return 1; | ||
| 99 | } | ||
| 100 | __setup("ima_template_fmt=", ima_template_fmt_setup); | ||
| 101 | |||
| 76 | static struct ima_template_desc *lookup_template_desc(const char *name) | 102 | static struct ima_template_desc *lookup_template_desc(const char *name) |
| 77 | { | 103 | { |
| 78 | int i; | 104 | int i; |
| @@ -146,12 +172,15 @@ static int template_desc_init_fields(const char *template_fmt, | |||
| 146 | } | 172 | } |
| 147 | } | 173 | } |
| 148 | 174 | ||
| 149 | *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL); | 175 | if (fields && num_fields) { |
| 150 | if (*fields == NULL) | 176 | *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL); |
| 151 | return -ENOMEM; | 177 | if (*fields == NULL) |
| 178 | return -ENOMEM; | ||
| 179 | |||
| 180 | memcpy(*fields, found_fields, i * sizeof(*fields)); | ||
| 181 | *num_fields = i; | ||
| 182 | } | ||
| 152 | 183 | ||
| 153 | memcpy(*fields, found_fields, i * sizeof(*fields)); | ||
| 154 | *num_fields = i; | ||
| 155 | return 0; | 184 | return 0; |
| 156 | } | 185 | } |
| 157 | 186 | ||
