Skip to content

Commit 7e24507

Browse files
authored
Merge pull request #1532 from val-ms/CLAM-1859-sha256-cache
- md5 -> sha2-256 caching - remove reliance on md5 hashes in general - FIPS cryptographic hash limits feature to disable md5 and sha1. - Adds related option for ClamD, ClamScan, Freshclam, Sigtool - ClamBC: fix crashes - signature names that start with "Weak." won't alert anymore. - ClamScan: - add `--hash-hint`, `--log-hash`, `--hash-alg`, `--file-type-hint`, `--log-file-type` - accurate counts for scanned bytes and bytes read - libclamav: - new cl_scan*_ex() APIs - separate temp-directory-recursion feature from keep-temps feature - object id's for each layer scanned - scan hash hints - scan file type hints - fix double-extraction for OOXML documents - new scan callbacks, deprecate old scan callbacks - new APIs to get access to file data and metadata from scan callbacks - metadata.json: - object id's - replace "viruses" to "alerts" and add "indicators" array - replace "FileMD5" with "sha2-256" - json store extra hashes feature - Related options for ClamD and ClamScan - object id's - related improvements
2 parents 17d0665 + 5314973 commit 7e24507

File tree

131 files changed

+10727
-3058
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+10727
-3058
lines changed

Cargo.lock

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

NEWS.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@ ClamAV 1.5.0 includes the following improvements and changes:
4747
Added two new APIs to the public clamav.h header:
4848
```c
4949
extern cl_error_t cl_cvdverify_ex(const char *file,
50-
const char *certs_directory);
50+
const char *certs_directory,
51+
uint32_t dboptions);
5152

5253
extern cl_error_t cl_cvdunpack_ex(const char *file,
5354
const char *dir,
54-
bool dont_verify,
55-
const char *certs_directory);
55+
const char *certs_directory,
56+
uint32_t dboptions);
5657
```
5758
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
5859

clamav-config.h.cmake.in

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,6 @@
367367
/* yara sources are compiled in */
368368
#define HAVE_YARA 1
369369

370-
/* For internal use only - DO NOT DEFINE */
371-
#cmakedefine HAVE__INTERNAL__SHA_COLLECT 1
372-
373370
/* Define as const if the declaration of iconv() needs const. */
374371
#cmakedefine ICONV_CONST @ICONV_CONST@
375372

clambc/bcrun.c

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -398,24 +398,16 @@ int main(int argc, char *argv[])
398398
fprintf(stderr, "Out of memory\n");
399399
exit(3);
400400
}
401-
ctx->ctx = &cctx;
402-
cctx.engine = engine;
403-
cctx.evidence = evidence_new();
401+
ctx->ctx = &cctx;
402+
cctx.engine = engine;
404403

405404
cctx.recursion_stack_size = cctx.engine->max_recursion_level;
406-
cctx.recursion_stack = calloc(sizeof(recursion_level_t), cctx.recursion_stack_size);
405+
cctx.recursion_stack = calloc(sizeof(cli_scan_layer_t), cctx.recursion_stack_size);
407406
if (!cctx.recursion_stack) {
408407
fprintf(stderr, "Out of memory\n");
409408
exit(3);
410409
}
411410

412-
// ctx was memset, so recursion_level starts at 0.
413-
cctx.recursion_stack[cctx.recursion_level].fmap = map;
414-
cctx.recursion_stack[cctx.recursion_level].type = CL_TYPE_ANY; /* ANY for the top level, because we don't yet know the type. */
415-
cctx.recursion_stack[cctx.recursion_level].size = map->len;
416-
417-
cctx.fmap = cctx.recursion_stack[cctx.recursion_level].fmap;
418-
419411
memset(&dbg_state, 0, sizeof(dbg_state));
420412
dbg_state.file = "<libclamav>";
421413
dbg_state.line = 0;
@@ -453,22 +445,34 @@ int main(int argc, char *argv[])
453445
optfree(opts);
454446
exit(5);
455447
}
456-
map = fmap(fd, 0, 0, opt->strarg);
448+
449+
map = fmap_new(fd, 0, 0, opt->strarg, opt->strarg);
457450
if (!map) {
458451
fprintf(stderr, "Unable to map input file %s\n", opt->strarg);
459452
exit(5);
460453
}
454+
455+
// ctx was memset, so recursion_level starts at 0.
456+
cctx.recursion_stack[cctx.recursion_level].fmap = map;
457+
cctx.recursion_stack[cctx.recursion_level].type = CL_TYPE_ANY; /* ANY for the top level, because we don't yet know the type. */
458+
cctx.recursion_stack[cctx.recursion_level].size = map->len;
459+
461460
rc = cli_bytecode_context_setfile(ctx, map);
462461
if (rc != CL_SUCCESS) {
463462
fprintf(stderr, "Unable to set file %s: %s\n", opt->strarg, cl_strerror(rc));
464463
optfree(opts);
465464
exit(5);
466465
}
467466
}
467+
468468
/* for testing */
469469
ctx->hooks.match_counts = deadbeefcounts;
470470
ctx->hooks.match_offsets = deadbeefcounts;
471-
rc = cli_bytecode_run(&bcs, bc, ctx);
471+
472+
/*
473+
* Run the bytecode.
474+
*/
475+
rc = cli_bytecode_run(&bcs, bc, ctx);
472476
if (rc != CL_SUCCESS) {
473477
fprintf(stderr, "Unable to run bytecode: %s\n", cl_strerror(rc));
474478
} else {
@@ -479,12 +483,15 @@ int main(int argc, char *argv[])
479483
if (debug_flag)
480484
printf("[clambc] Bytecode returned: 0x%llx\n", (long long)v);
481485
}
486+
482487
cli_bytecode_context_destroy(ctx);
483488
if (map)
484-
funmap(map);
485-
cl_engine_free(engine);
489+
fmap_free(map);
490+
if (cctx.recursion_stack[cctx.recursion_level].evidence) {
491+
evidence_free(cctx.recursion_stack[cctx.recursion_level].evidence);
492+
}
486493
free(cctx.recursion_stack);
487-
evidence_free(cctx.evidence);
494+
cl_engine_free(engine);
488495
}
489496
cli_bytecode_destroy(bc);
490497
cli_bytecode_done(&bcs);

clamd/clamd.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,8 +616,12 @@ int main(int argc, char **argv)
616616

617617
cl_engine_set_clcb_virus_found(engine, clamd_virus_found_cb);
618618

619-
if (optget(opts, "LeaveTemporaryFiles")->enabled)
619+
if (optget(opts, "LeaveTemporaryFiles")->enabled) {
620+
/* Set the engine to keep temporary files */
620621
cl_engine_set_num(engine, CL_ENGINE_KEEPTMP, 1);
622+
/* Also set the engine to create temporary directory structure */
623+
cl_engine_set_num(engine, CL_ENGINE_TMPDIR_RECURSION, 1);
624+
}
621625

622626
if (optget(opts, "ForceToDisk")->enabled)
623627
cl_engine_set_num(engine, CL_ENGINE_FORCETODISK, 1);
@@ -705,6 +709,12 @@ int main(int argc, char **argv)
705709
}
706710
}
707711

712+
if (optget(opts, "FIPSCryptoHashLimits")->enabled) {
713+
dboptions |= CL_DB_FIPS_LIMITS;
714+
cl_engine_set_num(engine, CL_ENGINE_FIPS_LIMITS, 1);
715+
logg(LOGG_INFO_NF, "FIPS crypto hash limits enabled.\n");
716+
}
717+
708718
if ((ret = cl_load(dbdir, engine, &sigs, dboptions))) {
709719
logg(LOGG_ERROR, "%s\n", cl_strerror(ret));
710720
ret = 1;

clamd/scanner.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ void msg_callback(enum cl_msg severity, const char *fullmsg, const char *msg, vo
9494
}
9595
}
9696

97-
void hash_callback(int fd, unsigned long long size, const unsigned char *md5, const char *virname, void *ctx)
97+
void hash_callback(int fd, unsigned long long size, const char *md5, const char *virname, void *ctx)
9898
{
9999
struct cb_context *c = ctx;
100100
UNUSEDPARAM(fd);
@@ -103,8 +103,8 @@ void hash_callback(int fd, unsigned long long size, const unsigned char *md5, co
103103
if (!c)
104104
return;
105105
c->virsize = size;
106-
strncpy(c->virhash, (const char *)md5, 32);
107-
c->virhash[32] = '\0';
106+
strncpy(c->virhash, md5, MD5_HASH_SIZE * 2);
107+
c->virhash[MD5_HASH_SIZE * 2] = '\0';
108108
}
109109

110110
void clamd_virus_found_cb(int fd, const char *virname, void *ctx)

clamd/scanner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ cl_error_t scanfd(const client_conn_t *conn, unsigned long int *scanned, const s
6969
int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *options, const struct optstruct *opts, char term);
7070
cl_error_t scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data);
7171
int scan_pathchk(const char *path, struct cli_ftw_cbdata *data);
72-
void hash_callback(int fd, unsigned long long size, const unsigned char *md5, const char *virname, void *ctx);
72+
void hash_callback(int fd, unsigned long long size, const char *md5, const char *virname, void *ctx);
7373
void msg_callback(enum cl_msg severity, const char *fullmsg, const char *msg, void *ctx);
7474
void clamd_virus_found_cb(int fd, const char *virname, void *context);
7575

clamd/server-th.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,11 +1379,6 @@ int recvloop(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigne
13791379
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED;
13801380
}
13811381

1382-
#ifdef HAVE__INTERNAL__SHA_COLLECT
1383-
if (optget(opts, "DevCollectHashes")->enabled)
1384-
options.dev |= CL_SCAN_DEV_COLLECT_SHA;
1385-
#endif
1386-
13871382
if (optget(opts, "GenerateMetadataJson")->enabled) {
13881383
options.general |= CL_SCAN_GENERAL_COLLECT_METADATA;
13891384
}
@@ -1396,6 +1391,10 @@ int recvloop(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigne
13961391
options.general |= CL_SCAN_GENERAL_STORE_PDF_URIS;
13971392
}
13981393

1394+
if (optget(opts, "JsonStoreExtraHashes")->enabled) {
1395+
options.general |= CL_SCAN_GENERAL_STORE_EXTRA_HASHES;
1396+
}
1397+
13991398
selfchk = optget(opts, "SelfCheck")->numarg;
14001399
if (!selfchk) {
14011400
logg(LOGG_INFO, "Self checking disabled.\n");

0 commit comments

Comments
 (0)