diff --git a/libclamav/libmspack.c b/libclamav/libmspack.c index f1a537dfd..9dcbe6957 100644 --- a/libclamav/libmspack.c +++ b/libclamav/libmspack.c @@ -34,7 +34,7 @@ struct mspack_name { struct mspack_system_ex { struct mspack_system ops; - off_t max_size; + uint64_t max_size; }; struct mspack_handle { @@ -45,7 +45,7 @@ struct mspack_handle { off_t offset; FILE *f; - off_t max_size; + uint64_t max_size; }; static struct mspack_file *mspack_fmap_open(struct mspack_system *self, @@ -170,7 +170,7 @@ static int mspack_fmap_write(struct mspack_file *file, void *buffer, int bytes) { struct mspack_handle *mspack_handle = (struct mspack_handle *)file; size_t count; - off_t max_size; + uint64_t max_size; if (bytes < 0 || !mspack_handle) { cli_dbgmsg("%s() err %d\n", __func__, __LINE__); @@ -189,7 +189,7 @@ static int mspack_fmap_write(struct mspack_file *file, void *buffer, int bytes) if (!max_size) return bytes; - max_size = max_size < (off_t)bytes ? max_size : (off_t)bytes; + max_size = max_size < (uint64_t)bytes ? max_size : (uint64_t)bytes; mspack_handle->max_size -= max_size; @@ -366,7 +366,7 @@ int cli_scanmscab(cli_ctx *ctx, off_t sfx_offset) } files = 0; for (cab_f = cab_h->files; cab_f; cab_f = cab_f->next) { - off_t max_size; + uint64_t max_size; char *tmp_fname = NULL; ret = cli_matchmeta(ctx, cab_f->filename, 0, cab_f->length, 0, @@ -387,13 +387,27 @@ int cli_scanmscab(cli_ctx *ctx, off_t sfx_offset) } } - if (ctx->engine->maxscansize && - ctx->scansize + ctx->engine->maxfilesize >= - ctx->engine->maxscansize) - max_size = ctx->engine->maxscansize - - ctx->scansize; - else - max_size = ctx->engine->maxfilesize ? ctx->engine->maxfilesize : 0xffffffff; + if (ctx->engine->maxfilesize > 0) { + // max filesize has been set + if ((ctx->engine->maxscansize > 0) && + (ctx->scansize + ctx->engine->maxfilesize >= ctx->engine->maxscansize)) { + // ... but would exceed max scansize, shrink it. + max_size = ctx->engine->maxscansize - ctx->scansize; + } else { + // ... and will work + max_size = ctx->engine->maxfilesize; + } + } else { + // max filesize not specified + if ((ctx->engine->maxscansize > 0) && + (ctx->scansize + UINT32_MAX >= ctx->engine->maxscansize)) { + // ... but UINT32_MAX would exceed max scansize, shrink it. + max_size = ctx->engine->maxscansize - ctx->scansize; + } else { + // ... use UINT32_MAX + max_size = UINT32_MAX; + } + } tmp_fname = cli_gentemp(ctx->sub_tmpdir); if (!tmp_fname) { @@ -468,7 +482,7 @@ int cli_scanmschm(cli_ctx *ctx) } files = 0; for (mschm_f = mschm_h->files; mschm_f; mschm_f = mschm_f->next) { - off_t max_size; + uint64_t max_size; char *tmp_fname; ret = cli_matchmeta(ctx, mschm_f->filename, 0, mschm_f->length, @@ -489,13 +503,27 @@ int cli_scanmschm(cli_ctx *ctx) } } - if (ctx->engine->maxscansize && - ctx->scansize + ctx->engine->maxfilesize >= - ctx->engine->maxscansize) - max_size = ctx->engine->maxscansize - - ctx->scansize; - else - max_size = ctx->engine->maxfilesize ? ctx->engine->maxfilesize : 0xffffffff; + if (ctx->engine->maxfilesize > 0) { + // max filesize has been set + if ((ctx->engine->maxscansize > 0) && + (ctx->scansize + ctx->engine->maxfilesize >= ctx->engine->maxscansize)) { + // ... but would exceed max scansize, shrink it. + max_size = ctx->engine->maxscansize - ctx->scansize; + } else { + // ... and will work + max_size = ctx->engine->maxfilesize; + } + } else { + // max filesize not specified + if ((ctx->engine->maxscansize > 0) && + (ctx->scansize + UINT32_MAX >= ctx->engine->maxscansize)) { + // ... but UINT32_MAX would exceed max scansize, shrink it. + max_size = ctx->engine->maxscansize - ctx->scansize; + } else { + // ... use UINT32_MAX + max_size = UINT32_MAX; + } + } ops_ex.max_size = max_size; diff --git a/libclamav/others.h b/libclamav/others.h index 4f72f1328..800c5fbc6 100644 --- a/libclamav/others.h +++ b/libclamav/others.h @@ -179,7 +179,7 @@ typedef struct cli_ctx_tag { unsigned long int *scanned; const struct cli_matcher *root; const struct cl_engine *engine; - unsigned long scansize; + uint64_t scansize; struct cl_scan_options *options; unsigned int scannedfiles; unsigned int found_possibly_unwanted; diff --git a/libclamav/scanners.c b/libclamav/scanners.c index eb682dc5f..e7afe5334 100644 --- a/libclamav/scanners.c +++ b/libclamav/scanners.c @@ -5462,7 +5462,7 @@ cl_error_t cl_scandesc_callback(int desc, const char *filename, const char **vir status = CL_CLEAN; goto done; } - if ((uint64_t)sb.st_size > engine->maxfilesize) { + if ((engine->maxfilesize > 0) && ((uint64_t)sb.st_size > engine->maxfilesize)) { cli_dbgmsg("cl_scandesc_callback: File too large (" STDu64 " bytes), ignoring\n", (uint64_t)sb.st_size); if (scanoptions->heuristic & CL_SCAN_HEURISTIC_EXCEEDS_MAX) { if (engine->cb_virus_found) @@ -5499,7 +5499,7 @@ done: cl_error_t cl_scanmap_callback(cl_fmap_t *map, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions, void *context) { - if (map->len > engine->maxfilesize) { + if ((engine->maxfilesize > 0) && (map->len > engine->maxfilesize)) { cli_dbgmsg("cl_scandesc_callback: File too large (%zu bytes), ignoring\n", map->len); if (scanoptions->heuristic & CL_SCAN_HEURISTIC_EXCEEDS_MAX) { if (engine->cb_virus_found)