Skip to content

Commit 9f3166b

Browse files
Roberto SassuMimi Zohar
authored andcommitted
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 <[email protected]> Signed-off-by: Mimi Zohar <[email protected]>
1 parent 7dbdb42 commit 9f3166b

File tree

1 file changed

+17
-13
lines changed

1 file changed

+17
-13
lines changed

security/integrity/ima/ima_template.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,34 +116,39 @@ static int template_desc_init_fields(const char *template_fmt,
116116
struct ima_template_field ***fields,
117117
int *num_fields)
118118
{
119-
char *c, *template_fmt_copy, *template_fmt_ptr;
119+
const char *template_fmt_ptr;
120120
int template_num_fields = template_fmt_size(template_fmt);
121-
int i, result = 0;
121+
int i, len, result = 0;
122122

123123
if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) {
124124
pr_err("format string '%s' contains too many fields\n",
125125
template_fmt);
126126
return -EINVAL;
127127
}
128128

129-
/* copying is needed as strsep() modifies the original buffer */
130-
template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL);
131-
if (template_fmt_copy == NULL)
132-
return -ENOMEM;
133-
134129
*fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL);
135130
if (*fields == NULL) {
136131
result = -ENOMEM;
137132
goto out;
138133
}
139134

140-
template_fmt_ptr = template_fmt_copy;
141-
for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL &&
142-
i < template_num_fields; i++) {
143-
struct ima_template_field *f = lookup_template_field(c);
135+
for (i = 0, template_fmt_ptr = template_fmt; i < template_num_fields;
136+
i++, template_fmt_ptr += len + 1) {
137+
char tmp_field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN + 1];
138+
struct ima_template_field *f;
139+
140+
len = strchrnul(template_fmt_ptr, '|') - template_fmt_ptr;
141+
if (len == 0 || len > IMA_TEMPLATE_FIELD_ID_MAX_LEN) {
142+
pr_err("Invalid field with length %d\n", len);
143+
result = -EINVAL;
144+
goto out;
145+
}
144146

147+
memcpy(tmp_field_id, template_fmt_ptr, len);
148+
tmp_field_id[len] = '\0';
149+
f = lookup_template_field(tmp_field_id);
145150
if (!f) {
146-
pr_err("field '%s' not found\n", c);
151+
pr_err("field '%s' not found\n", tmp_field_id);
147152
result = -ENOENT;
148153
goto out;
149154
}
@@ -155,7 +160,6 @@ static int template_desc_init_fields(const char *template_fmt,
155160
kfree(*fields);
156161
*fields = NULL;
157162
}
158-
kfree(template_fmt_copy);
159163
return result;
160164
}
161165

0 commit comments

Comments
 (0)