Skip to content

Commit

Permalink
Remove additional memory allocation limits relating to signature load
Browse files Browse the repository at this point in the history
Variables like the number of signature parts are considered trusted user input
and so allocations based on those values need not check the memory allocation
limit.

Specifically for the allocation of the normalized buffer in cli_scanscript,
I determined that the size of SCANBUFF is fixed and so safe, and the maxpatlen
comes from the signature load and is therefore also trusted, so we do not
need to check the allocation limit.
  • Loading branch information
micahsnyder committed Mar 15, 2024
1 parent 609ace2 commit 39070d1
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 57 deletions.
2 changes: 1 addition & 1 deletion libclamav/bytecode_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ uint8_t *cli_bcapi_malloc(struct cli_bc_ctx *ctx, uint32_t size)
}

if (0 == size || size > CLI_MAX_ALLOCATION) {
cli_warnmsg("cli_bcapi_malloc(): File or section is too large to scan (%zu bytes). For your safety, ClamAV limits how much memory an operation can allocate to %d bytes\n",
cli_warnmsg("cli_bcapi_malloc(): File or section is too large to scan (%u bytes). For your safety, ClamAV limits how much memory an operation can allocate to %d bytes\n",
size, CLI_MAX_ALLOCATION);
v = NULL;
} else {
Expand Down
40 changes: 20 additions & 20 deletions libclamav/matcher-ac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1412,7 +1412,7 @@ cl_error_t cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t

data->reloffsigs = reloffsigs;
if (reloffsigs) {
data->offset = (uint32_t *)cli_max_malloc(reloffsigs * 2 * sizeof(uint32_t));
data->offset = (uint32_t *)malloc(reloffsigs * 2 * sizeof(uint32_t));
if (!data->offset) {
cli_errmsg("cli_ac_init: Can't allocate memory for data->offset\n");
return CL_EMEM;
Expand All @@ -1423,7 +1423,7 @@ cl_error_t cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t

data->partsigs = partsigs;
if (partsigs) {
data->offmatrix = (uint32_t ***)cli_max_calloc(partsigs, sizeof(uint32_t **));
data->offmatrix = (uint32_t ***)calloc(partsigs, sizeof(uint32_t **));
if (!data->offmatrix) {
cli_errmsg("cli_ac_init: Can't allocate memory for data->offmatrix\n");

Expand All @@ -1436,7 +1436,7 @@ cl_error_t cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t

data->lsigs = lsigs;
if (lsigs) {
data->lsigcnt = (uint32_t **)cli_max_malloc(lsigs * sizeof(uint32_t *));
data->lsigcnt = (uint32_t **)malloc(lsigs * sizeof(uint32_t *));
if (!data->lsigcnt) {
if (partsigs)
free(data->offmatrix);
Expand All @@ -1447,7 +1447,7 @@ cl_error_t cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t
cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigcnt\n");
return CL_EMEM;
}
data->lsigcnt[0] = (uint32_t *)cli_max_calloc(lsigs * 64, sizeof(uint32_t));
data->lsigcnt[0] = (uint32_t *)calloc(lsigs * 64, sizeof(uint32_t));
if (!data->lsigcnt[0]) {
free(data->lsigcnt);
if (partsigs)
Expand All @@ -1461,7 +1461,7 @@ cl_error_t cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t
}
for (i = 1; i < lsigs; i++)
data->lsigcnt[i] = data->lsigcnt[0] + 64 * i;
data->yr_matches = (uint8_t *)cli_max_calloc(lsigs, sizeof(uint8_t));
data->yr_matches = (uint8_t *)calloc(lsigs, sizeof(uint8_t));
if (data->yr_matches == NULL) {
free(data->lsigcnt[0]);
free(data->lsigcnt);
Expand All @@ -1474,7 +1474,7 @@ cl_error_t cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t
}

/* subsig offsets */
data->lsig_matches = (struct cli_lsig_matches **)cli_max_calloc(lsigs, sizeof(struct cli_lsig_matches *));
data->lsig_matches = (struct cli_lsig_matches **)calloc(lsigs, sizeof(struct cli_lsig_matches *));
if (!data->lsig_matches) {
free(data->yr_matches);
free(data->lsigcnt[0]);
Expand All @@ -1488,8 +1488,8 @@ cl_error_t cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t
cli_errmsg("cli_ac_init: Can't allocate memory for data->lsig_matches\n");
return CL_EMEM;
}
data->lsigsuboff_last = (uint32_t **)cli_max_malloc(lsigs * sizeof(uint32_t *));
data->lsigsuboff_first = (uint32_t **)cli_max_malloc(lsigs * sizeof(uint32_t *));
data->lsigsuboff_last = (uint32_t **)malloc(lsigs * sizeof(uint32_t *));
data->lsigsuboff_first = (uint32_t **)malloc(lsigs * sizeof(uint32_t *));
if (!data->lsigsuboff_last || !data->lsigsuboff_first) {
free(data->lsig_matches);
free(data->lsigsuboff_last);
Expand All @@ -1506,8 +1506,8 @@ cl_error_t cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t
cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigsuboff_(last|first)\n");
return CL_EMEM;
}
data->lsigsuboff_last[0] = (uint32_t *)cli_max_calloc(lsigs * 64, sizeof(uint32_t));
data->lsigsuboff_first[0] = (uint32_t *)cli_max_calloc(lsigs * 64, sizeof(uint32_t));
data->lsigsuboff_last[0] = (uint32_t *)calloc(lsigs * 64, sizeof(uint32_t));
data->lsigsuboff_first[0] = (uint32_t *)calloc(lsigs * 64, sizeof(uint32_t));
if (!data->lsigsuboff_last[0] || !data->lsigsuboff_first[0]) {
free(data->lsig_matches);
free(data->lsigsuboff_last[0]);
Expand Down Expand Up @@ -1704,10 +1704,10 @@ cl_error_t lsig_sub_matched(const struct cli_matcher *root, struct cli_ac_data *

ls_matches = mdata->lsig_matches[lsig_id];
if (ls_matches == NULL) { /* allocate cli_lsig_matches */
ls_matches = mdata->lsig_matches[lsig_id] = (struct cli_lsig_matches *)cli_max_calloc(1, sizeof(struct cli_lsig_matches) +
(ac_lsig->tdb.subsigs - 1) * sizeof(struct cli_subsig_matches *));
ls_matches = mdata->lsig_matches[lsig_id] = (struct cli_lsig_matches *)calloc(1, sizeof(struct cli_lsig_matches) +
(ac_lsig->tdb.subsigs - 1) * sizeof(struct cli_subsig_matches *));
if (ls_matches == NULL) {
cli_errmsg("lsig_sub_matched: cli_max_calloc failed for cli_lsig_matches\n");
cli_errmsg("lsig_sub_matched: calloc failed for cli_lsig_matches\n");
return CL_EMEM;
}
ls_matches->subsigs = ac_lsig->tdb.subsigs;
Expand All @@ -1716,16 +1716,16 @@ cl_error_t lsig_sub_matched(const struct cli_matcher *root, struct cli_ac_data *
if (ss_matches == NULL) { /* allocate cli_subsig_matches */
ss_matches = ls_matches->matches[subsig_id] = malloc(sizeof(struct cli_subsig_matches));
if (ss_matches == NULL) {
cli_errmsg("lsig_sub_matched: cli_max_malloc failed for cli_subsig_matches struct\n");
cli_errmsg("lsig_sub_matched: malloc failed for cli_subsig_matches struct\n");
return CL_EMEM;
}
ss_matches->next = 0;
ss_matches->last = sizeof(ss_matches->offsets) / sizeof(uint32_t) - 1;
}
if (ss_matches->next > ss_matches->last) { /* cli_matches out of space? realloc */
ss_matches = ls_matches->matches[subsig_id] = cli_max_realloc(ss_matches, sizeof(struct cli_subsig_matches) + sizeof(uint32_t) * ss_matches->last * 2);
ss_matches = ls_matches->matches[subsig_id] = realloc(ss_matches, sizeof(struct cli_subsig_matches) + sizeof(uint32_t) * ss_matches->last * 2);
if (ss_matches == NULL) {
cli_errmsg("lsig_sub_matched: cli_max_realloc failed for cli_subsig_matches struct\n");
cli_errmsg("lsig_sub_matched: realloc failed for cli_subsig_matches struct\n");
return CL_EMEM;
}
ss_matches->last = sizeof(ss_matches->offsets) / sizeof(uint32_t) + ss_matches->last * 2 - 1;
Expand Down Expand Up @@ -1926,13 +1926,13 @@ cl_error_t cli_ac_scanbuff(

/* sparsely populated matrix, so allocate and initialize if NULL */
if (!mdata->offmatrix[pt->sigid - 1]) {
mdata->offmatrix[pt->sigid - 1] = cli_max_malloc(pt->parts * sizeof(int32_t *));
mdata->offmatrix[pt->sigid - 1] = malloc(pt->parts * sizeof(int32_t *));
if (!mdata->offmatrix[pt->sigid - 1]) {
cli_errmsg("cli_ac_scanbuff: Can't allocate memory for mdata->offmatrix[%u]\n", pt->sigid - 1);
return CL_EMEM;
}

mdata->offmatrix[pt->sigid - 1][0] = cli_max_malloc(pt->parts * (CLI_DEFAULT_AC_TRACKLEN + 2) * sizeof(uint32_t));
mdata->offmatrix[pt->sigid - 1][0] = malloc(pt->parts * (CLI_DEFAULT_AC_TRACKLEN + 2) * sizeof(uint32_t));
if (!mdata->offmatrix[pt->sigid - 1][0]) {
cli_errmsg("cli_ac_scanbuff: Can't allocate memory for mdata->offmatrix[%u][0]\n", pt->sigid - 1);
free(mdata->offmatrix[pt->sigid - 1]);
Expand Down Expand Up @@ -2589,7 +2589,7 @@ inline static int ac_special_altstr(const char *hexpr, uint8_t sigopts, struct c
special->type = AC_SPECIAL_ALT_STR;

/* allocate reusable subexpr */
if (!(subexpr = cli_max_calloc(slen + 1, sizeof(char)))) {
if (!(subexpr = calloc(slen + 1, sizeof(char)))) {
cli_errmsg("ac_special_altstr: Can't allocate subexpr container\n");
free(hexprcpy);
return CL_EMEM;
Expand Down Expand Up @@ -2751,7 +2751,7 @@ cl_error_t cli_ac_addsig(struct cli_matcher *root, const char *virname, const ch
}

hexnewsz = strlen(hexsig) + 1;
if (!(hexnew = (char *)cli_max_calloc(1, hexnewsz))) {
if (!(hexnew = (char *)calloc(1, hexnewsz))) {
MPOOL_FREE(root->mempool, new);
free(hexcpy);
return CL_EMEM;
Expand Down
4 changes: 2 additions & 2 deletions libclamav/matcher-bm.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,12 @@ cl_error_t cli_bm_initoff(const struct cli_matcher *root, struct cli_bm_off *dat
}

data->cnt = data->pos = 0;
data->offtab = (uint32_t *)cli_max_malloc(root->bm_patterns * sizeof(uint32_t));
data->offtab = (uint32_t *)malloc(root->bm_patterns * sizeof(uint32_t));
if (!data->offtab) {
cli_errmsg("cli_bm_initoff: Can't allocate memory for data->offtab\n");
return CL_EMEM;
}
data->offset = (uint32_t *)cli_max_malloc(root->bm_patterns * sizeof(uint32_t));
data->offset = (uint32_t *)malloc(root->bm_patterns * sizeof(uint32_t));
if (!data->offset) {
cli_errmsg("cli_bm_initoff: Can't allocate memory for data->offset\n");
free(data->offtab);
Expand Down
4 changes: 2 additions & 2 deletions libclamav/matcher-byte-comp.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#include "str.h"

/* DEBUGGING */
//#define MATCHER_BCOMP_DEBUG
// #define MATCHER_BCOMP_DEBUG
#ifdef MATCHER_BCOMP_DEBUG
#define bcm_dbgmsg(...) cli_dbgmsg(__VA_ARGS__)
#else
Expand Down Expand Up @@ -855,7 +855,7 @@ uint16_t cli_bcomp_chk_hex(const unsigned char *buffer, uint16_t opt, uint32_t l
}

/**
* @brief multipurpose buffer normalization support function for bytecompare
* @brief multipurpose buffer normalization support function for byte-compare
*
* Currently can be used to normalize a little endian hex buffer to big endian.
* Can also be used to trim whitespace from the front of the buffer.
Expand Down
6 changes: 3 additions & 3 deletions libclamav/matcher-pcre.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
#endif

/* DEBUGGING */
//#define MATCHER_PCRE_DEBUG
// #define MATCHER_PCRE_DEBUG
#ifdef MATCHER_PCRE_DEBUG
#define pm_dbgmsg(...) cli_dbgmsg(__VA_ARGS__)
#else
Expand Down Expand Up @@ -471,12 +471,12 @@ cl_error_t cli_pcre_recaloff(struct cli_matcher *root, struct cli_pcre_off *data
}

/* allocate data structures */
data->shift = (uint32_t *)cli_max_calloc(root->pcre_metas, sizeof(uint32_t));
data->shift = (uint32_t *)calloc(root->pcre_metas, sizeof(uint32_t));
if (!data->shift) {
cli_errmsg("cli_pcre_initoff: cannot allocate memory for data->shift\n");
return CL_EMEM;
}
data->offset = (uint32_t *)cli_max_calloc(root->pcre_metas, sizeof(uint32_t));
data->offset = (uint32_t *)calloc(root->pcre_metas, sizeof(uint32_t));
if (!data->offset) {
cli_errmsg("cli_pcre_initoff: cannot allocate memory for data->offset\n");
free(data->shift);
Expand Down
6 changes: 3 additions & 3 deletions libclamav/others.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ struct cl_engine *cl_engine_new(void)
}

/* Set up default stats/intel gathering callbacks */
intel = cli_max_calloc(1, sizeof(cli_intel_t));
intel = calloc(1, sizeof(cli_intel_t));
if ((intel)) {
#ifdef CL_THREAD_SAFE
if (pthread_mutex_init(&(intel->mutex), NULL)) {
Expand Down Expand Up @@ -1279,7 +1279,7 @@ char *cli_hashstream(FILE *fs, unsigned char *digcpy, int type)

cl_finish_hash(ctx, digest);

if (!(hashstr = (char *)cli_max_calloc(size * 2 + 1, sizeof(char))))
if (!(hashstr = (char *)calloc(size * 2 + 1, sizeof(char))))
return NULL;

pt = hashstr;
Expand Down Expand Up @@ -1819,7 +1819,7 @@ bitset_t *cli_bitset_init(void)
return NULL;
}
bs->length = BITSET_DEFAULT_SIZE;
bs->bitset = cli_max_calloc(BITSET_DEFAULT_SIZE, 1);
bs->bitset = calloc(BITSET_DEFAULT_SIZE, 1);
if (!bs->bitset) {
cli_errmsg("cli_bitset_init: Unable to allocate memory for bs->bitset %u\n", BITSET_DEFAULT_SIZE);
free(bs);
Expand Down
2 changes: 1 addition & 1 deletion libclamav/phishcheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ static int build_regex(regex_t* preg, const char* regex, int nosub)
if (rc) {

size_t buflen = cli_regerror(rc, preg, NULL, 0);
char* errbuf = cli_max_malloc(buflen);
char* errbuf = malloc(buflen);

if (errbuf) {
cli_regerror(rc, preg, errbuf, buflen);
Expand Down
Loading

0 comments on commit 39070d1

Please sign in to comment.