aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity/ima/ima_template.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity/ima/ima_template.c')
-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,
116 struct ima_template_field ***fields, 116 struct ima_template_field ***fields,
117 int *num_fields) 117 int *num_fields)
118{ 118{
119 char *c, *template_fmt_copy, *template_fmt_ptr; 119 const char *template_fmt_ptr;
120 int template_num_fields = template_fmt_size(template_fmt); 120 int template_num_fields = template_fmt_size(template_fmt);
121 int i, result = 0; 121 int i, len, result = 0;
122 122
123 if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) { 123 if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) {
124 pr_err("format string '%s' contains too many fields\n", 124 pr_err("format string '%s' contains too many fields\n",
@@ -126,24 +126,29 @@ static int template_desc_init_fields(const char *template_fmt,
126 return -EINVAL; 126 return -EINVAL;
127 } 127 }
128 128
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
134 *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL); 129 *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL);
135 if (*fields == NULL) { 130 if (*fields == NULL) {
136 result = -ENOMEM; 131 result = -ENOMEM;
137 goto out; 132 goto out;
138 } 133 }
139 134
140 template_fmt_ptr = template_fmt_copy; 135 for (i = 0, template_fmt_ptr = template_fmt; i < template_num_fields;
141 for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL && 136 i++, template_fmt_ptr += len + 1) {
142 i < template_num_fields; i++) { 137 char tmp_field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN + 1];
143 struct ima_template_field *f = lookup_template_field(c); 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 }
144 146
147 memcpy(tmp_field_id, template_fmt_ptr, len);
148 tmp_field_id[len] = '\0';
149 f = lookup_template_field(tmp_field_id);
145 if (!f) { 150 if (!f) {
146 pr_err("field '%s' not found\n", c); 151 pr_err("field '%s' not found\n", tmp_field_id);
147 result = -ENOENT; 152 result = -ENOENT;
148 goto out; 153 goto out;
149 } 154 }
@@ -155,7 +160,6 @@ out:
155 kfree(*fields); 160 kfree(*fields);
156 *fields = NULL; 161 *fields = NULL;
157 } 162 }
158 kfree(template_fmt_copy);
159 return result; 163 return result;
160} 164}
161 165