Merge remote-tracking branches 'asoc/fix/atmel', 'asoc/fix/fsl', 'asoc/fix/tegra...
[linux-drm-fsl-dcu.git] / security / integrity / ima / ima_template.c
index 4e5da990630beca2c179894db96fd9f20d31bc17..635695f6a185a1d24ee3d1bfb05d4f7ebe8cedb0 100644 (file)
@@ -90,7 +90,7 @@ static struct ima_template_field *lookup_template_field(const char *field_id)
        return NULL;
 }
 
-static int template_fmt_size(char *template_fmt)
+static int template_fmt_size(const char *template_fmt)
 {
        char c;
        int template_fmt_len = strlen(template_fmt);
@@ -106,22 +106,29 @@ static int template_fmt_size(char *template_fmt)
        return j + 1;
 }
 
-static int template_desc_init_fields(char *template_fmt,
+static int template_desc_init_fields(const char *template_fmt,
                                     struct ima_template_field ***fields,
                                     int *num_fields)
 {
-       char *c, *template_fmt_ptr = template_fmt;
+       char *c, *template_fmt_copy, *template_fmt_ptr;
        int template_num_fields = template_fmt_size(template_fmt);
        int i, result = 0;
 
        if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX)
                return -EINVAL;
 
+       /* copying is needed as strsep() modifies the original buffer */
+       template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL);
+       if (template_fmt_copy == NULL)
+               return -ENOMEM;
+
        *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL);
        if (*fields == NULL) {
                result = -ENOMEM;
                goto out;
        }
+
+       template_fmt_ptr = template_fmt_copy;
        for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL &&
             i < template_num_fields; i++) {
                struct ima_template_field *f = lookup_template_field(c);
@@ -133,10 +140,12 @@ static int template_desc_init_fields(char *template_fmt,
                (*fields)[i] = f;
        }
        *num_fields = i;
-       return 0;
 out:
-       kfree(*fields);
-       *fields = NULL;
+       if (result < 0) {
+               kfree(*fields);
+               *fields = NULL;
+       }
+       kfree(template_fmt_copy);
        return result;
 }