Fix minor leaks when loading malformed PDB signatures

This commit fixes a couple of minor memory leaks that may occur when loading
malformed PDB signatures 

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=43849
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=44115
This commit is contained in:
ragusaa 2022-05-27 19:51:18 -04:00 committed by GitHub
parent 1c6746853f
commit 62bf3bea32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 51 deletions

View file

@ -1314,31 +1314,6 @@ uint8_t cli_set_debug_flag(uint8_t debug_flag);
} while (0)
#endif
/**
* @brief Wrapper around realloc that limits how much may be allocated to CLI_MAX_ALLOCATION.
*
* IMPORTANT: This differs from realloc() in that if size==0, it will NOT free the ptr.
*
* NOTE: cli_realloc() will NOT free var if size==0. It is safe to free var after `done:`.
*
* @param ptr
* @param size
* @return void*
*/
#ifndef CLI_REALLOC
#define CLI_REALLOC(var, size, ...) \
do { \
void *vTmp = cli_realloc(var, size); \
if (NULL == vTmp) { \
do { \
__VA_ARGS__; \
} while (0); \
goto done; \
} \
var = vTmp; \
} while (0)
#endif
/**
* @brief Wrapper around realloc that limits how much may be allocated to CLI_MAX_ALLOCATION.
*
@ -1364,4 +1339,18 @@ uint8_t cli_set_debug_flag(uint8_t debug_flag);
} while (0)
#endif
/*This is a duplicate from other PR's.*/
#ifndef CLI_STRDUP
#define CLI_STRDUP(buf, var, ...) \
do { \
var = cli_strdup(buf); \
if (NULL == var) { \
do { \
__VA_ARGS__; \
} while (0); \
goto done; \
} \
} while (0)
#endif
#endif

View file

@ -170,24 +170,24 @@ static void destroy_tree(struct node *n)
break;
case leaf_class:
if (n->u.leaf_class_bitmap != dot_bitmap)
free(n->u.leaf_class_bitmap);
FREE(n->u.leaf_class_bitmap);
break;
case root:
case leaf:
break;
}
free(n);
FREE(n);
}
static uint8_t *parse_char_class(const uint8_t *pat, size_t *pos)
{
unsigned char range_start = 0;
int hasprev = 0;
uint8_t *bitmap = cli_malloc(32);
if (!bitmap) {
cli_errmsg("parse_char_class: Unable to allocate memory for bitmap\n");
return NULL;
}
uint8_t *bitmap = NULL;
CLI_MALLOC(bitmap, 32,
cli_errmsg("parse_char_class: Unable to allocate memory for bitmap\n"));
if (pat[*pos] == '^') {
memset(bitmap, 0xFF, 32); /*match chars not in brackets*/
++*pos;
@ -200,14 +200,15 @@ static uint8_t *parse_char_class(const uint8_t *pat, size_t *pos)
unsigned char range_end;
unsigned int c;
if (0 == range_start) {
FREE(bitmap);
cli_errmsg("parse_char_class: range_start not initialized");
return NULL;
goto done;
}
++*pos;
if (pat[*pos] == '[')
if (pat[*pos + 1] == '.') {
/* collating sequence not handled */
free(bitmap);
FREE(bitmap);
/* we are parsing the regex for a
* filter, be conservative and
* tell the filter that anything could
@ -225,7 +226,7 @@ static uint8_t *parse_char_class(const uint8_t *pat, size_t *pos)
hasprev = 0;
} else if (pat[*pos] == '[' && pat[*pos] == ':') {
/* char class */
free(bitmap);
FREE(bitmap);
while (pat[*pos] != ']') ++*pos;
++*pos;
while (pat[*pos] != ']') ++*pos;
@ -237,6 +238,8 @@ static uint8_t *parse_char_class(const uint8_t *pat, size_t *pos)
hasprev = 1;
}
} while (pat[*pos] != ']');
done:
return bitmap;
}
@ -252,8 +255,10 @@ static struct node *parse_regex(const uint8_t *p, size_t *last)
++*last;
right = parse_regex(p, last);
v = make_node(alternate, v, right);
if (!v)
if (!v) {
destroy_tree(right);
return NULL;
}
break;
case '*':
case '?':
@ -265,25 +270,31 @@ static struct node *parse_regex(const uint8_t *p, size_t *last)
case '+':
/* (x)* */
tmp = make_node(optional, v, NULL);
if (!tmp)
if (!tmp) {
destroy_tree(v);
return NULL;
}
/* (x) */
right = dup_node(v);
if (!right) {
free(tmp);
destroy_tree(tmp);
return NULL;
}
/* (x)*(x) => (x)+ */
v = make_node(concat, tmp, right);
if (!v)
if (!v) {
destroy_tree(right);
return NULL;
}
++*last;
break;
case '(':
++*last;
right = parse_regex(p, last);
if (!right)
if (!right) {
destroy_tree(v);
return NULL;
}
++*last;
v = make_node(concat, v, right);
break;
@ -291,8 +302,10 @@ static struct node *parse_regex(const uint8_t *p, size_t *last)
return v;
case '.':
right = make_charclass(dot_bitmap);
if (!right)
if (!right) {
destroy_tree(v);
return NULL;
}
v = make_node(concat, v, right);
if (!v)
return NULL;
@ -301,11 +314,15 @@ static struct node *parse_regex(const uint8_t *p, size_t *last)
case '[':
++*last;
right = make_charclass(parse_char_class(p, last));
if (!right)
if (!right) {
destroy_tree(v);
return NULL;
}
v = make_node(concat, v, right);
if (!v)
if (!v) {
destroy_tree(right);
return NULL;
}
++*last;
break;
case '\\':
@ -315,8 +332,10 @@ static struct node *parse_regex(const uint8_t *p, size_t *last)
default:
right = make_leaf(p[*last]);
v = make_node(concat, v, right);
if (!v)
if (!v) {
destroy_tree(right);
return NULL;
}
++*last;
break;
}
@ -435,8 +454,11 @@ cl_error_t cli_regex2suffix(const char *pattern, regex_t *preg, suffix_callback
size_t last = 0;
int rc;
VERIFY_POINTER(pattern, cli_errmsg("cli_regex2suffix: pattern must be initialized"); rc = CL_ENULLARG);
VERIFY_POINTER(preg, cli_errmsg("cli_regex2suffix: preg must be initialized"); rc = CL_ENULLARG);
if (NULL == pattern) {
cli_errmsg("cli_regex2suffix: pattern can't be NULL");
rc = REG_INVARG;
goto done;
}
regex.preg = preg;
rc = cli_regcomp(regex.preg, pattern, REG_EXTENDED);
@ -453,11 +475,15 @@ cl_error_t cli_regex2suffix(const char *pattern, regex_t *preg, suffix_callback
return rc;
}
regex.nxt = NULL;
CLI_STRDUP(pattern, regex.pattern, cli_errmsg("cli_regex2suffix: Unable to duplicate pattern"); rc = CL_EMEM);
CLI_STRDUP(pattern, regex.pattern,
cli_errmsg("cli_regex2suffix: unable to strdup regex.pattern");
rc = REG_ESPACE);
n = parse_regex(((const uint8_t *)pattern), &last);
if (!n)
return REG_ESPACE;
n = parse_regex(pattern, &last);
if (!n) {
rc = REG_ESPACE;
goto done;
}
memset(&buf, 0, sizeof(buf));
memset(&root_node, 0, sizeof(buf));
n->parent = &root_node;
@ -465,7 +491,6 @@ cl_error_t cli_regex2suffix(const char *pattern, regex_t *preg, suffix_callback
rc = build_suffixtree_descend(n, &buf, cb, cbdata, &regex);
done:
FREE(regex.pattern);
FREE(buf.data);
destroy_tree(n);