On Thu, 2013-12-05 at 09:49 +0100, Roberto Sassu wrote: > On 12/04/2013 10:05 PM, Mimi Zohar wrote: > > On Thu, 2013-11-07 at 15:00 +0100, Roberto Sassu wrote: > >> 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. > >> > >> Signed-off-by: Roberto Sassu <roberto.sa...@polito.it> > >> --- > >> Documentation/kernel-parameters.txt | 4 +++ > >> Documentation/security/IMA-templates.txt | 29 +++++++++--------- > >> security/integrity/ima/ima_template.c | 50 > >> ++++++++++++++++++++++++++++++++ > >> 3 files changed, 68 insertions(+), 15 deletions(-) > >> > >> diff --git a/Documentation/kernel-parameters.txt > >> b/Documentation/kernel-parameters.txt > >> index 1e8761c..27b14b2 100644 > >> --- a/Documentation/kernel-parameters.txt > >> +++ b/Documentation/kernel-parameters.txt > >> @@ -1199,6 +1199,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" } > >> + > >> init= [KNL] > >> Format: <full_path> > >> Run specified binary instead of /sbin/init as init > >> diff --git a/Documentation/security/IMA-templates.txt > >> b/Documentation/security/IMA-templates.txt > >> index a777e5f..08ea2da 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 > >> 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 all defined template descriptors > >> +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, > >> @@ -84,4 +81,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='. > >> diff --git a/security/integrity/ima/ima_template.c > >> b/security/integrity/ima/ima_template.c > >> index bb33576..5a95d06 100644 > >> --- a/security/integrity/ima/ima_template.c > >> +++ b/security/integrity/ima/ima_template.c > >> @@ -21,6 +21,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[] = { > >> @@ -38,12 +39,16 @@ 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 struct ima_template_field *lookup_template_field(const char > >> *field_id); > >> > >> 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. > >> @@ -70,6 +75,48 @@ 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); > >> + char *str_ptr_start = str; > >> + char *str_ptr_end = str_ptr_start; > >> + > >> + if (ima_template) > >> + return 1; > >> + > >> + while (str_ptr_start != NULL) { > >> + char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN]; > >> + int len; > >> + > >> + str_ptr_end = strpbrk(str_ptr_start, "|"); > >> + if (str_ptr_end == NULL) > >> + len = str + strlen(str) - str_ptr_start; > >> + else > >> + len = str_ptr_end++ - str_ptr_start; > >> + > >> + if (len >= IMA_TEMPLATE_FIELD_ID_MAX_LEN) { > >> + pr_err("IMA: field too long, using template %s\n", > >> + CONFIG_IMA_DEFAULT_TEMPLATE); > >> + return 1; > >> + } > >> + > >> + memcpy(field_id, str_ptr_start, len); > >> + field_id[len] = '\0'; > >> + if (lookup_template_field(field_id) == NULL) { > >> + pr_err("IMA: field '%s' not found, using template %s\n", > >> + field_id, CONFIG_IMA_DEFAULT_TEMPLATE); > >> + return 1; > >> + } > >> + > >> + str_ptr_start = str_ptr_end; > >> + } > >> + > > > > Roberto, looking this over again, I think this can be simplified by > > using strsep(). > > > > Hi Mimi > > yes, the code can be simplified. However, I did not use strsep() > to avoid that this function modifies the kernel command line > (it replaces the passed separator character with '\0'). > Since the custom format string is parsed again later, I also > have to revert changes made by strsep().
Somehow the code needs to be simplified and cleaned up. For example, str_ptr_start/end need to be renamed to something simpler, like field/field_end or token/token_end. (Refer to Documentation/CodingStyle chapter 4 for variable naming style.) Perhaps, instead of using strsep(), write a function to return a pointer to the field and field length. thanks, Mimi > > > >> + 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; > >> @@ -160,6 +207,9 @@ static int init_defined_templates(void) > >> for (i = 0; i < ARRAY_SIZE(defined_templates); i++) { > >> struct ima_template_desc *template = &defined_templates[i]; > >> > >> + if (strlen(template->fmt) == 0) > >> + continue; > >> + > >> result = template_desc_init_fields(template->fmt, > >> &(template->fields), > >> &(template->num_fields)); > > > > > > -- > To unsubscribe from this list: send the line "unsubscribe > linux-security-module" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/