aboutsummaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorRoberto Sassu2014-10-13 14:08:40 +0200
committerMimi Zohar2014-10-13 08:39:01 -0400
commit9f3166b8ca3b89c27b9f1c9039d3662ab7812cfa (patch)
tree8477845f161e24a8833f9436430cd20a7e34dae9 /security
parent7dbdb4206bd69bf518fd76e01f4c5c64cda96455 (diff)
ima: don't allocate a copy of template_fmt in template_desc_init_fields()
This patch removes the allocation of a copy of 'template_fmt', needed for iterating over all fields in the passed template format string. The removal was possible by replacing strcspn(), which modifies the passed string, with strchrnul(). The currently processed template field is copied in a temporary variable. The purpose of this change is use template_desc_init_fields() in two ways: for just validating a template format string (the function should work if called by a setup function, when memory cannot be allocated), and for actually initializing a template descriptor. The implementation of this feature will be complete with the next patch. Changelog: - v3: - added 'goto out' in template_desc_init_fields() to free allocated memory if a template field length is not valid (suggested by Mimi Zohar) Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security')
-rw-r--r--security/integrity/ima/ima_template.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index b7b359ca39ee..d93a58e603df 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -116,9 +116,9 @@ static int template_desc_init_fields(const char *template_fmt,
struct ima_template_field ***fields,
int *num_fields)
{
- char *c, *template_fmt_copy, *template_fmt_ptr;
+ const char *template_fmt_ptr;
int template_num_fields = template_fmt_size(template_fmt);
- int i, result = 0;
+ int i, len, result = 0;
if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) {
pr_err("format string '%s' contains too many fields\n",
@@ -126,24 +126,29 @@ static int template_desc_init_fields(const char *template_fmt,
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);
+ for (i = 0, template_fmt_ptr = template_fmt; i < template_num_fields;
+ i++, template_fmt_ptr += len + 1) {
+ char tmp_field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN + 1];
+ struct ima_template_field *f;
+
+ len = strchrnul(template_fmt_ptr, '|') - template_fmt_ptr;
+ if (len == 0 || len > IMA_TEMPLATE_FIELD_ID_MAX_LEN) {
+ pr_err("Invalid field with length %d\n", len);
+ result = -EINVAL;
+ goto out;
+ }
+ memcpy(tmp_field_id, template_fmt_ptr, len);
+ tmp_field_id[len] = '\0';
+ f = lookup_template_field(tmp_field_id);
if (!f) {
- pr_err("field '%s' not found\n", c);
+ pr_err("field '%s' not found\n", tmp_field_id);
result = -ENOENT;
goto out;
}
@@ -155,7 +160,6 @@ out:
kfree(*fields);
*fields = NULL;
}
- kfree(template_fmt_copy);
return result;
}