mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
			
			
This commit is contained in:
		
							parent
							
								
									1bd7face74
								
							
						
					
					
						commit
						c2426d2ad5
					
				
					 3 changed files with 52 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -1318,6 +1318,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 | 
			
		|||
			Formats: { "ima" | "ima-ng" }
 | 
			
		||||
			Default: "ima-ng"
 | 
			
		||||
 | 
			
		||||
	ima_template_fmt=
 | 
			
		||||
	                [IMA] Define a custom template format.
 | 
			
		||||
			Format: { "field1|...|fieldN" }
 | 
			
		||||
 | 
			
		||||
	ima.ahash_minsize= [IMA] Minimum file size for asynchronous hash usage
 | 
			
		||||
			Format: <min_file_size>
 | 
			
		||||
			Set the minimal file size for using asynchronous hash.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,25 +27,22 @@ Managing templates with these structures is very simple. To support
 | 
			
		|||
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,
 | 
			
		||||
| 
						 | 
				
			
			@ -86,4 +83,6 @@ currently the following methods are supported:
 | 
			
		|||
 - 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='.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,7 @@ 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"},
 | 
			
		||||
	{.name = "", .fmt = ""},	/* placeholder for a custom format */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct ima_template_field supported_fields[] = {
 | 
			
		||||
| 
						 | 
				
			
			@ -41,12 +42,18 @@ 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.
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +80,25 @@ static int __init ima_template_setup(char *str)
 | 
			
		|||
}
 | 
			
		||||
__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;
 | 
			
		||||
| 
						 | 
				
			
			@ -146,12 +172,15 @@ static int template_desc_init_fields(const char *template_fmt,
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue