Skip to content
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
aa7b7e9
Swap clean cache from MD5 to SHA2-256
val-ms Jun 3, 2025
f7e60d5
Record unique object-id for each layer scanned
val-ms Jun 8, 2025
81baf60
For metadata JSON feature, also save URIs for contained HTML files
val-ms Jun 8, 2025
7f25b92
Record scan matches (evidence) at each recursion layer
val-ms Jun 9, 2025
31dcec1
libclamav: Add engine option to toggle temp directory recursion
val-ms Jun 10, 2025
87a2957
ClamBC: fix crashes on startup
val-ms Jun 10, 2025
ff42820
Reformat clamav.h for readability
val-ms Jun 10, 2025
e64590d
libclamav: Add 'ex'-scan functions to API w. hash and type in/out par…
val-ms Jun 16, 2025
466c875
ClamScan: Add hash & file-type in/out CLI options
val-ms Jun 16, 2025
b4f0d68
Tests: Add clamscan tests for new hash and file-type options
val-ms Jun 16, 2025
d0853bf
Fix double-extraction of OOXML-based office documents
val-ms Jun 17, 2025
42c4a88
Always run callbacks for embedded files
val-ms Jun 18, 2025
f05770f
libclamav: scan-layer callback API functions
val-ms Jun 22, 2025
51adfb8
ClamScan & libclamav: improve precision of bytes-scanned, bytes-read
val-ms Jun 25, 2025
13c4788
FIPS & FIPS-like limits on hash algs for cryptographic uses
val-ms Jul 2, 2025
4660141
Auto-format touch-up
val-ms Jul 2, 2025
f302a2c
Update generated Rust sys.rs interface
val-ms Jul 2, 2025
1478763
NSIS: When extracting files, get the path's basename when recording t…
val-ms Jul 2, 2025
cf11815
ClamsScan: add missing --json-store-extra-hashes option to help and m…
val-ms Jul 18, 2025
91072db
Tests: Enable --fips-limits for fp-check tests
val-ms Jul 18, 2025
8e1fb00
Tests: clamscan --fips-limits for CVD loading
val-ms Jul 18, 2025
3255ec1
clamav.h: cl_fmap_get_hash() output paramater is allocated, not const
val-ms Jul 23, 2025
e223ddb
Example program: demonstrate more features and support scripted inputs
val-ms Jul 23, 2025
9d25367
Add missing message string when printing CL_BREAK code
val-ms Jul 25, 2025
6d9b57e
libclamav: cl_scan*_ex() functions provide verdict separate from errors
val-ms Jul 28, 2025
ed3e1e5
Added additional ex_scan_callbacks test and fixed a couple related bugs
val-ms Jul 29, 2025
520971d
Replace CL_CLEAN with CL_SUCCESS in clamav.h, and scanners.c
val-ms Jul 29, 2025
39fa618
Example Program: Add --disable-cache feature
val-ms Jul 31, 2025
0ea66b5
libclamav: Fix issue reporting trusted verdicts
val-ms Aug 7, 2025
3975c43
metadata JSON: Rename "Viruses" key to "Alerts"
val-ms Aug 7, 2025
3b23133
Metadata JSON: Simplify recording alerts and indicators
val-ms Aug 11, 2025
b34ea5e
Minor improvement to debug log messages from code review
val-ms Aug 12, 2025
27fe03c
Fix OpenSSL 1 compatibility issue, plus minor improvements
val-ms Aug 17, 2025
5314973
Update generated sys.rs file
val-ms Aug 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ ClamAV 1.5.0 includes the following improvements and changes:
Added two new APIs to the public clamav.h header:
```c
extern cl_error_t cl_cvdverify_ex(const char *file,
const char *certs_directory);
const char *certs_directory,
uint32_t dboptions);

extern cl_error_t cl_cvdunpack_ex(const char *file,
const char *dir,
bool dont_verify,
const char *certs_directory);
const char *certs_directory,
uint32_t dboptions);
```
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.

Expand Down
3 changes: 0 additions & 3 deletions clamav-config.h.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,6 @@
/* yara sources are compiled in */
#define HAVE_YARA 1

/* For internal use only - DO NOT DEFINE */
#cmakedefine HAVE__INTERNAL__SHA_COLLECT 1

/* Define as const if the declaration of iconv() needs const. */
#cmakedefine ICONV_CONST @ICONV_CONST@

Expand Down
39 changes: 23 additions & 16 deletions clambc/bcrun.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,24 +398,16 @@ int main(int argc, char *argv[])
fprintf(stderr, "Out of memory\n");
exit(3);
}
ctx->ctx = &cctx;
cctx.engine = engine;
cctx.evidence = evidence_new();
ctx->ctx = &cctx;
cctx.engine = engine;

cctx.recursion_stack_size = cctx.engine->max_recursion_level;
cctx.recursion_stack = calloc(sizeof(recursion_level_t), cctx.recursion_stack_size);
cctx.recursion_stack = calloc(sizeof(cli_scan_layer_t), cctx.recursion_stack_size);
if (!cctx.recursion_stack) {
fprintf(stderr, "Out of memory\n");
exit(3);
}

// ctx was memset, so recursion_level starts at 0.
cctx.recursion_stack[cctx.recursion_level].fmap = map;
cctx.recursion_stack[cctx.recursion_level].type = CL_TYPE_ANY; /* ANY for the top level, because we don't yet know the type. */
cctx.recursion_stack[cctx.recursion_level].size = map->len;

cctx.fmap = cctx.recursion_stack[cctx.recursion_level].fmap;

memset(&dbg_state, 0, sizeof(dbg_state));
dbg_state.file = "<libclamav>";
dbg_state.line = 0;
Expand Down Expand Up @@ -453,22 +445,34 @@ int main(int argc, char *argv[])
optfree(opts);
exit(5);
}
map = fmap(fd, 0, 0, opt->strarg);

map = fmap_new(fd, 0, 0, opt->strarg, opt->strarg);
if (!map) {
fprintf(stderr, "Unable to map input file %s\n", opt->strarg);
exit(5);
}

// ctx was memset, so recursion_level starts at 0.
cctx.recursion_stack[cctx.recursion_level].fmap = map;
cctx.recursion_stack[cctx.recursion_level].type = CL_TYPE_ANY; /* ANY for the top level, because we don't yet know the type. */
cctx.recursion_stack[cctx.recursion_level].size = map->len;

rc = cli_bytecode_context_setfile(ctx, map);
if (rc != CL_SUCCESS) {
fprintf(stderr, "Unable to set file %s: %s\n", opt->strarg, cl_strerror(rc));
optfree(opts);
exit(5);
}
}

/* for testing */
ctx->hooks.match_counts = deadbeefcounts;
ctx->hooks.match_offsets = deadbeefcounts;
rc = cli_bytecode_run(&bcs, bc, ctx);

/*
* Run the bytecode.
*/
rc = cli_bytecode_run(&bcs, bc, ctx);
if (rc != CL_SUCCESS) {
fprintf(stderr, "Unable to run bytecode: %s\n", cl_strerror(rc));
} else {
Expand All @@ -479,12 +483,15 @@ int main(int argc, char *argv[])
if (debug_flag)
printf("[clambc] Bytecode returned: 0x%llx\n", (long long)v);
}

cli_bytecode_context_destroy(ctx);
if (map)
funmap(map);
cl_engine_free(engine);
fmap_free(map);
if (cctx.recursion_stack[cctx.recursion_level].evidence) {
evidence_free(cctx.recursion_stack[cctx.recursion_level].evidence);
}
free(cctx.recursion_stack);
evidence_free(cctx.evidence);
cl_engine_free(engine);
}
cli_bytecode_destroy(bc);
cli_bytecode_done(&bcs);
Expand Down
12 changes: 11 additions & 1 deletion clamd/clamd.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,12 @@ int main(int argc, char **argv)

cl_engine_set_clcb_virus_found(engine, clamd_virus_found_cb);

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

if (optget(opts, "ForceToDisk")->enabled)
cl_engine_set_num(engine, CL_ENGINE_FORCETODISK, 1);
Expand Down Expand Up @@ -705,6 +709,12 @@ int main(int argc, char **argv)
}
}

if (optget(opts, "FIPSCryptoHashLimits")->enabled) {
dboptions |= CL_DB_FIPS_LIMITS;
cl_engine_set_num(engine, CL_ENGINE_FIPS_LIMITS, 1);
logg(LOGG_INFO_NF, "FIPS crypto hash limits enabled.\n");
}

if ((ret = cl_load(dbdir, engine, &sigs, dboptions))) {
logg(LOGG_ERROR, "%s\n", cl_strerror(ret));
ret = 1;
Expand Down
6 changes: 3 additions & 3 deletions clamd/scanner.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ void msg_callback(enum cl_msg severity, const char *fullmsg, const char *msg, vo
}
}

void hash_callback(int fd, unsigned long long size, const unsigned char *md5, const char *virname, void *ctx)
void hash_callback(int fd, unsigned long long size, const char *md5, const char *virname, void *ctx)
{
struct cb_context *c = ctx;
UNUSEDPARAM(fd);
Expand All @@ -103,8 +103,8 @@ void hash_callback(int fd, unsigned long long size, const unsigned char *md5, co
if (!c)
return;
c->virsize = size;
strncpy(c->virhash, (const char *)md5, 32);
c->virhash[32] = '\0';
strncpy(c->virhash, md5, MD5_HASH_SIZE * 2);
c->virhash[MD5_HASH_SIZE * 2] = '\0';
}

void clamd_virus_found_cb(int fd, const char *virname, void *ctx)
Expand Down
2 changes: 1 addition & 1 deletion clamd/scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ cl_error_t scanfd(const client_conn_t *conn, unsigned long int *scanned, const s
int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *options, const struct optstruct *opts, char term);
cl_error_t scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data);
int scan_pathchk(const char *path, struct cli_ftw_cbdata *data);
void hash_callback(int fd, unsigned long long size, const unsigned char *md5, const char *virname, void *ctx);
void hash_callback(int fd, unsigned long long size, const char *md5, const char *virname, void *ctx);
void msg_callback(enum cl_msg severity, const char *fullmsg, const char *msg, void *ctx);
void clamd_virus_found_cb(int fd, const char *virname, void *context);

Expand Down
9 changes: 4 additions & 5 deletions clamd/server-th.c
Original file line number Diff line number Diff line change
Expand Up @@ -1379,11 +1379,6 @@ int recvloop(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigne
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED;
}

#ifdef HAVE__INTERNAL__SHA_COLLECT
if (optget(opts, "DevCollectHashes")->enabled)
options.dev |= CL_SCAN_DEV_COLLECT_SHA;
#endif

if (optget(opts, "GenerateMetadataJson")->enabled) {
options.general |= CL_SCAN_GENERAL_COLLECT_METADATA;
}
Expand All @@ -1396,6 +1391,10 @@ int recvloop(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigne
options.general |= CL_SCAN_GENERAL_STORE_PDF_URIS;
}

if (optget(opts, "JsonStoreExtraHashes")->enabled) {
options.general |= CL_SCAN_GENERAL_STORE_EXTRA_HASHES;
}

selfchk = optget(opts, "SelfCheck")->numarg;
if (!selfchk) {
logg(LOGG_INFO, "Self checking disabled.\n");
Expand Down
Loading
Loading