aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorRoberto Sassu <roberto.sassu@polito.it>2014-02-03 07:56:05 -0500
committerMimi Zohar <zohar@linux.vnet.ibm.com>2014-03-07 11:32:30 -0500
commite3b64c268b485f578a498c2f6d5704ef54ab4432 (patch)
tree0612967837f6afe8b78da21d803146bbc1c8ddf6 /security
parentc019e307ad82a8ee652b8ccbacf69ae94263b07b (diff)
ima: reduce memory usage when a template containing the n field is used
Before this change, to correctly calculate the template digest for the 'ima' template, the event name field (id: 'n') length was set to the fixed size of 256 bytes. This patch reduces the length of the event name field to the string length incremented of one (to make room for the termination character '\0') and handles the specific case of the digest calculation for the 'ima' template directly in ima_calc_field_array_hash_tfm(). 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_crypto.c11
-rw-r--r--security/integrity/ima/ima_template_lib.c19
2 files changed, 13 insertions, 17 deletions
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index fdf60def52e9..d8b55c952005 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -161,15 +161,22 @@ static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data,
161 return rc; 161 return rc;
162 162
163 for (i = 0; i < num_fields; i++) { 163 for (i = 0; i < num_fields; i++) {
164 u8 buffer[IMA_EVENT_NAME_LEN_MAX + 1] = { 0 };
165 u8 *data_to_hash = field_data[i].data;
166 u32 datalen = field_data[i].len;
167
164 if (strcmp(td->name, IMA_TEMPLATE_IMA_NAME) != 0) { 168 if (strcmp(td->name, IMA_TEMPLATE_IMA_NAME) != 0) {
165 rc = crypto_shash_update(&desc.shash, 169 rc = crypto_shash_update(&desc.shash,
166 (const u8 *) &field_data[i].len, 170 (const u8 *) &field_data[i].len,
167 sizeof(field_data[i].len)); 171 sizeof(field_data[i].len));
168 if (rc) 172 if (rc)
169 break; 173 break;
174 } else if (strcmp(td->fields[i]->field_id, "n") == 0) {
175 memcpy(buffer, data_to_hash, datalen);
176 data_to_hash = buffer;
177 datalen = IMA_EVENT_NAME_LEN_MAX + 1;
170 } 178 }
171 rc = crypto_shash_update(&desc.shash, field_data[i].data, 179 rc = crypto_shash_update(&desc.shash, data_to_hash, datalen);
172 field_data[i].len);
173 if (rc) 180 if (rc)
174 break; 181 break;
175 } 182 }
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index e8592e7bfc21..1506f0248572 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -27,7 +27,6 @@ static bool ima_template_hash_algo_allowed(u8 algo)
27enum data_formats { 27enum data_formats {
28 DATA_FMT_DIGEST = 0, 28 DATA_FMT_DIGEST = 0,
29 DATA_FMT_DIGEST_WITH_ALGO, 29 DATA_FMT_DIGEST_WITH_ALGO,
30 DATA_FMT_EVENT_NAME,
31 DATA_FMT_STRING, 30 DATA_FMT_STRING,
32 DATA_FMT_HEX 31 DATA_FMT_HEX
33}; 32};
@@ -37,18 +36,10 @@ static int ima_write_template_field_data(const void *data, const u32 datalen,
37 struct ima_field_data *field_data) 36 struct ima_field_data *field_data)
38{ 37{
39 u8 *buf, *buf_ptr; 38 u8 *buf, *buf_ptr;
40 u32 buflen; 39 u32 buflen = datalen;
41 40
42 switch (datafmt) { 41 if (datafmt == DATA_FMT_STRING)
43 case DATA_FMT_EVENT_NAME:
44 buflen = IMA_EVENT_NAME_LEN_MAX + 1;
45 break;
46 case DATA_FMT_STRING:
47 buflen = datalen + 1; 42 buflen = datalen + 1;
48 break;
49 default:
50 buflen = datalen;
51 }
52 43
53 buf = kzalloc(buflen, GFP_KERNEL); 44 buf = kzalloc(buflen, GFP_KERNEL);
54 if (!buf) 45 if (!buf)
@@ -63,7 +54,7 @@ static int ima_write_template_field_data(const void *data, const u32 datalen,
63 * split into multiple template fields (the space is the delimitator 54 * split into multiple template fields (the space is the delimitator
64 * character for measurements lists in ASCII format). 55 * character for measurements lists in ASCII format).
65 */ 56 */
66 if (datafmt == DATA_FMT_EVENT_NAME || datafmt == DATA_FMT_STRING) { 57 if (datafmt == DATA_FMT_STRING) {
67 for (buf_ptr = buf; buf_ptr - buf < datalen; buf_ptr++) 58 for (buf_ptr = buf; buf_ptr - buf < datalen; buf_ptr++)
68 if (*buf_ptr == ' ') 59 if (*buf_ptr == ' ')
69 *buf_ptr = '_'; 60 *buf_ptr = '_';
@@ -281,8 +272,6 @@ static int ima_eventname_init_common(struct integrity_iint_cache *iint,
281{ 272{
282 const char *cur_filename = NULL; 273 const char *cur_filename = NULL;
283 u32 cur_filename_len = 0; 274 u32 cur_filename_len = 0;
284 enum data_formats fmt = size_limit ?
285 DATA_FMT_EVENT_NAME : DATA_FMT_STRING;
286 275
287 BUG_ON(filename == NULL && file == NULL); 276 BUG_ON(filename == NULL && file == NULL);
288 277
@@ -305,7 +294,7 @@ static int ima_eventname_init_common(struct integrity_iint_cache *iint,
305 cur_filename_len = IMA_EVENT_NAME_LEN_MAX; 294 cur_filename_len = IMA_EVENT_NAME_LEN_MAX;
306out: 295out:
307 return ima_write_template_field_data(cur_filename, cur_filename_len, 296 return ima_write_template_field_data(cur_filename, cur_filename_len,
308 fmt, field_data); 297 DATA_FMT_STRING, field_data);
309} 298}
310 299
311/* 300/*