mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2025-10-19 10:23:17 +00:00
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:
parent
1c6746853f
commit
62bf3bea32
2 changed files with 65 additions and 51 deletions
|
@ -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
|
||||
|
|
|
@ -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, ®ex);
|
||||
|
||||
done:
|
||||
|
||||
FREE(regex.pattern);
|
||||
FREE(buf.data);
|
||||
destroy_tree(n);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue