Skip to content

Commit 3223673

Browse files
committed
Fix parsing of envvars in MCA files
This commit fixes a memory corruption bug when parsing lines of the form: -x FOO=bar The code was making changes to the size of the buffer allocated for key_buffer without making the appropriate changes to key_buffer_len. This was causing subsequent calls to save_param_name to write to invalid memory. This commit makes the following changes: - Fix the above bug by modifying trim_name to move the string within the buffer instead of re-allocating space for the trimmed string. - Cleaned up both trim_name and save_param_name. Both functions took a prefix and suffix to trim. Problem was the prefix was not treated like a prefix. Instead the "prefix" was located inside the string using strstr then the trimmed value started after the substring (even in the middle of the string). To allow trimming both -x and --x (as well as -mca and --mca) trim_name is now called with each prefix. Signed-off-by: Nathan Hjelm <[email protected]>
1 parent d544e0e commit 3223673

File tree

1 file changed

+55
-38
lines changed

1 file changed

+55
-38
lines changed

opal/util/keyval_parse.c

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* University of Stuttgart. All rights reserved.
1111
* Copyright (c) 2004-2005 The Regents of the University of California.
1212
* All rights reserved.
13-
* Copyright (c) 2015 Los Alamos National Security, LLC. All rights
13+
* Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights
1414
* reserved.
1515
* $COPYRIGHT$
1616
*
@@ -27,6 +27,7 @@
2727
#include "opal/util/output.h"
2828
#include "opal/threads/mutex.h"
2929
#include <string.h>
30+
#include <ctype.h>
3031

3132
int opal_util_keyval_parse_lineno = 0;
3233

@@ -200,53 +201,58 @@ int opal_util_keyval_save_internal_envars(opal_keyval_parse_fn_t callback)
200201
return OPAL_SUCCESS;
201202
}
202203

203-
static int trim_name(char **buffer, const char* prefix, const char* suffix)
204+
static void trim_name(char *buffer, const char* prefix, const char* suffix)
204205
{
205-
char *pchr, *echr, *tmp;
206-
int size;
207-
if (NULL == *buffer) {
208-
return 1;
206+
char *pchr, *echr;
207+
size_t buffer_len;
208+
209+
if (NULL == buffer) {
210+
return;
209211
}
210-
pchr = *buffer;
212+
213+
buffer_len = strlen (buffer);
214+
215+
pchr = buffer;
211216
if (NULL != prefix) {
212-
pchr = strstr(*buffer, prefix);
213-
if (NULL != pchr) {
214-
pchr += strlen(prefix);
215-
} else {
216-
pchr = *buffer;
217+
size_t prefix_len = strlen (prefix);
218+
219+
if (0 == strncmp (buffer, prefix, prefix_len)) {
220+
pchr += prefix_len;
217221
}
218222
}
223+
219224
/* trim spaces at the beginning */
220-
while (' ' == *pchr || '\t' == *pchr) {
225+
while (isspace (*pchr)) {
221226
pchr++;
222227
}
228+
223229
/* trim spaces at the end */
224-
echr = *buffer+strlen(*buffer)-1;
225-
while (' ' == *echr || '\t' == *echr || '\n' == *echr) {
230+
echr = buffer + buffer_len - 1;
231+
while (isspace (*echr)) {
226232
echr--;
227233
}
228-
echr++;
229-
*echr = '\0';
234+
echr[1] = '\0';
235+
230236
if (NULL != suffix) {
231-
if (!strncmp(echr-strlen(suffix), suffix, strlen(suffix))) {
232-
echr -= strlen(suffix)+1;
233-
while (' ' == *echr || '\t' == *echr) {
237+
size_t suffix_len = strlen (suffix);
238+
239+
echr -= suffix_len - 1;
240+
241+
if (0 == strncmp (echr, suffix, strlen(suffix))) {
242+
do {
234243
echr--;
235-
}
236-
echr++;
237-
*echr = '\0';
244+
} while (isspace (*echr));
245+
echr[1] = '\0';
238246
}
239247
}
240-
size = strlen(pchr)+1;
241-
tmp = malloc(size);
242-
strncpy(tmp, pchr, size);
243-
*buffer = realloc(*buffer, size);
244-
strncpy(*buffer, tmp, size);
245-
free(tmp);
246-
return 0;
248+
249+
if (buffer != pchr) {
250+
/* move the trimmed string to the beginning of the buffer */
251+
memmove (buffer, pchr, strlen (pchr) + 1);
252+
}
247253
}
248254

249-
static int save_param_name(const char* prefix, const char* suffix)
255+
static int save_param_name (void)
250256
{
251257
if (key_buffer_len < strlen(opal_util_keyval_yytext) + 1) {
252258
char *tmp;
@@ -261,8 +267,8 @@ static int save_param_name(const char* prefix, const char* suffix)
261267
key_buffer = tmp;
262268
}
263269

264-
strncpy(key_buffer, opal_util_keyval_yytext, key_buffer_len);
265-
trim_name(&key_buffer, prefix, suffix);
270+
strncpy (key_buffer, opal_util_keyval_yytext, key_buffer_len);
271+
266272
return OPAL_SUCCESS;
267273
}
268274

@@ -309,18 +315,26 @@ static int parse_line_new(opal_keyval_parse_state_t first_val)
309315
{
310316
opal_keyval_parse_state_t val;
311317
char *tmp;
318+
int rc;
312319

313320
val = first_val;
314321
while (OPAL_UTIL_KEYVAL_PARSE_NEWLINE != val && OPAL_UTIL_KEYVAL_PARSE_DONE != val) {
322+
rc = save_param_name ();
323+
if (OPAL_SUCCESS != rc) {
324+
return rc;
325+
}
326+
315327
if (OPAL_UTIL_KEYVAL_PARSE_MCAVAR == val) {
316-
save_param_name("-mca", NULL);
328+
trim_name (key_buffer, "-mca", NULL);
329+
trim_name (key_buffer, "--mca", NULL);
330+
317331
val = opal_util_keyval_yylex();
318332
if (OPAL_UTIL_KEYVAL_PARSE_VALUE == val) {
319333
if (NULL != opal_util_keyval_yytext) {
320334
tmp = strdup(opal_util_keyval_yytext);
321335
if ('\'' == tmp[0] || '\"' == tmp[0]) {
322-
trim_name(&tmp, "\'", "\'");
323-
trim_name(&tmp, "\"", "\"");
336+
trim_name (tmp, "\'", "\'");
337+
trim_name (tmp, "\"", "\"");
324338
}
325339
keyval_callback(key_buffer, tmp);
326340
free(tmp);
@@ -330,7 +344,9 @@ static int parse_line_new(opal_keyval_parse_state_t first_val)
330344
return OPAL_ERROR;
331345
}
332346
} else if (OPAL_UTIL_KEYVAL_PARSE_ENVEQL == val) {
333-
save_param_name("-x", "=");
347+
trim_name (key_buffer, "-x", "=");
348+
trim_name (key_buffer, "--x", NULL);
349+
334350
val = opal_util_keyval_yylex();
335351
if (OPAL_UTIL_KEYVAL_PARSE_VALUE == val) {
336352
add_to_env_str(key_buffer, opal_util_keyval_yytext);
@@ -339,7 +355,8 @@ static int parse_line_new(opal_keyval_parse_state_t first_val)
339355
return OPAL_ERROR;
340356
}
341357
} else if (OPAL_UTIL_KEYVAL_PARSE_ENVVAR == val) {
342-
save_param_name("-x", "=");
358+
trim_name (key_buffer, "-x", "=");
359+
trim_name (key_buffer, "--x", NULL);
343360
add_to_env_str(key_buffer, NULL);
344361
} else {
345362
/* we got something unexpected. Bonk! */

0 commit comments

Comments
 (0)