Commit b624871cb for clamav.net
commit b624871cbc9f962870d5018db9cfa73576ddd133
Author: John Humlick <15677335+jhumlick@users.noreply.github.com>
Date: Wed Jan 21 09:17:14 2026 -0800
libclamav: Malformed regexes result in misleading memory error messages. (#1635)
The regex parsing code treated anything that did not return CL_SUCCESS
as CL_EMEM in several places, resulting in a return code indicative of a
malformed database returning a memory error instead. This change passes
the real return code up the chain, and also prevents trying to realloc 0
bytes when we don't have anything to realloc due to a malformed
database.
CLAM-2191
diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c
index 2e1de60f5..2ba0ce046 100644
--- a/libclamav/regex_list.c
+++ b/libclamav/regex_list.c
@@ -833,6 +833,10 @@ static cl_error_t add_pattern_suffix(void *cbdata, const char *suffix, size_t su
if (CL_SUCCESS != ret) {
cli_hashtab_delete(&matcher->suffix_hash, suffix, suffix_len);
+ /* Check if there is anything to shrink back to */
+ if (n == 0) {
+ goto done;
+ }
/*shrink the size back to what it was.*/
CLI_MAX_REALLOC_OR_GOTO_DONE(matcher->suffix_regexes, n * sizeof(*matcher->suffix_regexes));
} else {
diff --git a/libclamav/regex_suffix.c b/libclamav/regex_suffix.c
index 076872098..e45b31a5d 100644
--- a/libclamav/regex_suffix.c
+++ b/libclamav/regex_suffix.c
@@ -394,9 +394,7 @@ static cl_error_t build_suffixtree_ascend(struct node *n, struct text_buffer *bu
cnt++;
if (cnt > 16) {
textbuffer_putc(buf, '\0');
- if (cb(cbdata, buf->data, buf->pos - 1, regex) != CL_SUCCESS)
- return CL_EMEM;
- return CL_SUCCESS;
+ return cb(cbdata, buf->data, buf->pos - 1, regex);
}
/* handle small classes by expanding */
for (i = 0; i < 255; i++) {
@@ -412,11 +410,9 @@ static cl_error_t build_suffixtree_ascend(struct node *n, struct text_buffer *bu
return 0;
case concat:
if (prev != n->u.children.left) {
- if (build_suffixtree_descend(n->u.children.left, buf, cb, cbdata, regex) != CL_SUCCESS)
- return CL_EMEM;
+ return build_suffixtree_descend(n->u.children.left, buf, cb, cbdata, regex);
/* we're done here, descend will call
* ascend if needed */
- return CL_SUCCESS;
} else {
n = n->parent;
}
@@ -438,6 +434,7 @@ static cl_error_t build_suffixtree_ascend(struct node *n, struct text_buffer *bu
static cl_error_t build_suffixtree_descend(struct node *n, struct text_buffer *buf, suffix_callback cb, void *cbdata, struct regex_list *regex)
{
size_t pos;
+ cl_error_t ret = CL_SUCCESS;
while (n && n->type == concat) {
n = n->u.children.right;
}
@@ -449,23 +446,23 @@ static cl_error_t build_suffixtree_descend(struct node *n, struct text_buffer *b
case alternate:
/* save pos as restart point */
pos = buf->pos;
- if (build_suffixtree_descend(n->u.children.left, buf, cb, cbdata, regex) != CL_SUCCESS)
- return CL_EMEM;
+ if ((ret = build_suffixtree_descend(n->u.children.left, buf, cb, cbdata, regex)) != CL_SUCCESS) {
+ return ret;
+ }
buf->pos = pos;
- if (build_suffixtree_descend(n->u.children.right, buf, cb, cbdata, regex) != CL_SUCCESS)
- return CL_EMEM;
+ if ((ret = build_suffixtree_descend(n->u.children.right, buf, cb, cbdata, regex)) != CL_SUCCESS) {
+ return ret;
+ }
buf->pos = pos;
break;
case optional:
textbuffer_putc(buf, '\0');
- if (cb(cbdata, buf->data, buf->pos - 1, regex) != CL_SUCCESS)
- return CL_EMEM;
- return CL_SUCCESS;
+ if ((ret = cb(cbdata, buf->data, buf->pos - 1, regex)) != CL_SUCCESS) {
+ return ret;
+ }
case leaf:
case leaf_class:
- if (build_suffixtree_ascend(n, buf, NULL, cb, cbdata, regex) != CL_SUCCESS)
- return CL_EMEM;
- return CL_SUCCESS;
+ return build_suffixtree_ascend(n, buf, NULL, cb, cbdata, regex);
default:
break;
}