a new data type, developers define the field identifier and implement
two functions, init() and show(), respectively to generate and display
measurement entries. Defining a new template descriptor requires
-specifying the template format, a string of field identifiers separated
-by the '|' character. While in the current implementation it is possible
-to define new template descriptors only by adding their definition in the
-template specific code (ima_template.c), in a future version it will be
-possible to register a new template on a running kernel by supplying to IMA
-the desired format string. In this version, IMA initializes at boot time
-all defined template descriptors by translating the format into an array
-of template fields structures taken from the set of the supported ones.
+specifying the template format (a string of field identifiers separated
+by the '|' character) through the 'ima_template_fmt' kernel command line
+parameter. At boot time, IMA initializes the chosen template descriptor
+by translating the format into an array of template fields structures taken
+from the set of the supported ones.
After the initialization step, IMA will call ima_alloc_init_template()
(new function defined within the patches for the new template management
mechanism) to generate a new measurement entry by using the template
descriptor chosen through the kernel configuration or through the newly
-introduced 'ima_template=' kernel command line parameter. It is during this
-phase that the advantages of the new architecture are clearly shown:
-the latter function will not contain specific code to handle a given template
-but, instead, it simply calls the init() method of the template fields
-associated to the chosen template descriptor and store the result (pointer
-to allocated data and data length) in the measurement entry structure.
+introduced 'ima_template' and 'ima_template_fmt' kernel command line parameters.
+It is during this phase that the advantages of the new architecture are
+clearly shown: the latter function will not contain specific code to handle
+a given template but, instead, it simply calls the init() method of the template
+fields associated to the chosen template descriptor and store the result
+(pointer to allocated data and data length) in the measurement entry structure.
The same mechanism is employed to display measurements entries.
The functions ima[_ascii]_measurements_show() retrieve, for each entry,
- select a template descriptor among those supported in the kernel
configuration ('ima-ng' is the default choice);
- specify a template descriptor name from the kernel command line through
- the 'ima_template=' parameter.
+ the 'ima_template=' parameter;
+ - register a new template descriptor with custom format through the kernel
+ command line parameter 'ima_template_fmt='.
{.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"},
+ {.name = "", .fmt = ""}, /* placeholder for a custom format */
};
static struct ima_template_field supported_fields[] = {
static struct ima_template_desc *ima_template;
static struct ima_template_desc *lookup_template_desc(const char *name);
+static int template_desc_init_fields(const char *template_fmt,
+ struct ima_template_field ***fields,
+ int *num_fields);
static int __init ima_template_setup(char *str)
{
struct ima_template_desc *template_desc;
int template_len = strlen(str);
+ if (ima_template)
+ return 1;
+
/*
* Verify that a template with the supplied name exists.
* If not, use CONFIG_IMA_DEFAULT_TEMPLATE.
}
__setup("ima_template=", ima_template_setup);
+static int __init ima_template_fmt_setup(char *str)
+{
+ int num_templates = ARRAY_SIZE(defined_templates);
+
+ 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;
+ }
+
+ defined_templates[num_templates - 1].fmt = str;
+ ima_template = defined_templates + num_templates - 1;
+ return 1;
+}
+__setup("ima_template_fmt=", ima_template_fmt_setup);
+
static struct ima_template_desc *lookup_template_desc(const char *name)
{
int i;
}
}
- *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL);
- if (*fields == NULL)
- return -ENOMEM;
+ 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;
+ }
- memcpy(*fields, found_fields, i * sizeof(*fields));
- *num_fields = i;
return 0;
}