Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ ClamAV 1.5.0 includes the following improvements and changes:
cl_error_t cl_fmap_get_path(cl_fmap_t *map, const char **path_out, size_t *offset_out, size_t *len_out);
cl_error_t cl_fmap_get_fd(const cl_fmap_t *map, int *fd_out, size_t *offset_out, size_t *len_out);
cl_error_t cl_fmap_get_size(const cl_fmap_t *map, size_t *size_out);
cl_error_t cl_fmap_set_hash(const cl_fmap_t *map, const char *hash_alg, char hash);
cl_error_t cl_fmap_set_hash(const cl_fmap_t *map, const char *hash_alg, const char *hash);
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the cl_fmap_set_hash() public prototype is adjusted (e.g., to const uint8_t * to indicate a binary digest buffer), please keep this NEWS.md API listing in sync so it accurately reflects the shipped signature.

Suggested change
cl_error_t cl_fmap_set_hash(const cl_fmap_t *map, const char *hash_alg, const char *hash);
cl_error_t cl_fmap_set_hash(const cl_fmap_t *map, const char *hash_alg, const uint8_t *hash);

Copilot uses AI. Check for mistakes.
cl_error_t cl_fmap_have_hash(const cl_fmap_t *map, const char *hash_alg, bool *have_hash_out);
cl_error_t cl_fmap_will_need_hash_later(const cl_fmap_t *map, const char *hash_alg);
cl_error_t cl_fmap_get_hash(const cl_fmap_t *map, const char *hash_alg, char **hash_out);
Expand Down
21 changes: 10 additions & 11 deletions libclamav/clamav.h
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ extern cl_error_t cl_fmap_set_name(cl_fmap_t *map, const char *name);
*
* @param map The file map to query.
* @param[out] name_out Pointer to a variable to receive the name of the file map.
* @return const char* The name of the file map, or NULL if not set.
* @return cl_error_t CL_SUCCESS if the name was retrieved successfully.
*/
extern cl_error_t cl_fmap_get_name(cl_fmap_t *map, const char **name_out);

Expand Down Expand Up @@ -635,7 +635,7 @@ extern cl_error_t cl_fmap_set_path(cl_fmap_t *map, const char *path);
* @param[out] offset_out (optional) Pointer to a variable to receive the offset of the current layer within the given file.
* @param[out] len_out (optional) Pointer to a variable to receive the length of the current layer within the given file.
* @return cl_error_t CL_SUCCESS if the path was successfully retrieved.
* CL_EACCES if the map does not have a file descriptor.
* CL_EACCES if the map does not have a stored path.
* CL_ENULLARG if null arguments were provided.
*/
extern cl_error_t cl_fmap_get_path(cl_fmap_t *map, const char **path_out, size_t *offset_out, size_t *len_out);
Expand Down Expand Up @@ -685,10 +685,10 @@ extern cl_error_t cl_fmap_get_size(const cl_fmap_t *map, size_t *size_out);
*
* @param map The file map to modify.
* @param hash_alg The hash algorithm to use (e.g., "md5", "sha1", "sha2-256").
* @param hash The hash value to set.
* @param hash Pointer to the hash value to set.
* @return cl_error_t CL_SUCCESS if the hash was successfully set.
*/
extern cl_error_t cl_fmap_set_hash(const cl_fmap_t *map, const char *hash_alg, char hash);
extern cl_error_t cl_fmap_set_hash(const cl_fmap_t *map, const char *hash_alg, const char *hash);

Comment on lines 686 to 692
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new cl_fmap_set_hash(..., const char *hash) prototype/documentation is ambiguous: the hash value is a binary digest buffer (may contain NUL bytes), not a C string. Consider using const uint8_t * (or const void *) and documenting that the buffer must be at least the digest length for hash_alg (e.g., 16 bytes for md5, 32 for sha2-256).

Copilot uses AI. Check for mistakes.
/**
* @brief Check if we already calculated a file hash of a specific type.
Expand Down Expand Up @@ -1636,12 +1636,12 @@ extern cl_error_t cl_scandesc_callback(
* This callback variant allows the caller to provide a context structure that
* caller provided callback functions can interpret.
*
* This extended version of cl_scanmap_callback allows the caller to provide
* This extended version of cl_scandesc_callback allows the caller to provide
* additional hints to the scanning engine, such as a file hash and file type.
*
* This variant also upgrades the `scanned` output parameter to a 64-bit integer.
*
* @param desc File descriptor of an open file. The caller must provide this or the map.
* @param desc File descriptor of an open file.
* @param filename (Optional) Filepath of the open file descriptor or file map.
* @param[out] verdict_out A pointer to a cl_verdict_t that will be set to the scan verdict.
* You should check the verdict even if the function returns an error.
Expand Down Expand Up @@ -1737,7 +1737,7 @@ extern cl_error_t cl_scanfile_callback(
* This callback variant allows the caller to provide a context structure that
* caller provided callback functions can interpret.
*
* This extended version of cl_scanmap_callback allows the caller to provide
* This extended version of cl_scanfile_callback allows the caller to provide
* additional hints to the scanning engine, such as a file hash and file type.
*
* This variant also upgrades the `scanned` output parameter to a 64-bit integer.
Expand Down Expand Up @@ -1797,7 +1797,7 @@ extern cl_error_t cl_scanfile_ex(
* - `cl_fmap_open_handle()` for a file handle, or
* - `cl_fmap_open_memory()` for a memory buffer.
*
* After the scan, you can also get the file hash with `cl_fmap_get_file_hash()`.
* After the scan, you can also get the file hash with `cl_fmap_get_hash()`.
*
* @param map Buffer to be scanned, in form of a cl_fmap_t.
* @param filename Name of data origin. Does not need to be an actual
Expand Down Expand Up @@ -1831,7 +1831,7 @@ extern cl_error_t cl_scanmap_callback(
* - `cl_fmap_open_handle()` for a file handle, or
* - `cl_fmap_open_memory()` for a memory buffer.
*
* After the scan, you can also get the file hash with `cl_fmap_get_file_hash()`.
* After the scan, you can also get the file hash with `cl_fmap_get_hash()`.
*
* This extended version of cl_scanmap_callback allows the caller to provide
* additional hints to the scanning engine, such as a file hash and file type.
Expand Down Expand Up @@ -1959,13 +1959,12 @@ extern cl_error_t cl_cvdverify(const char *file);
/**
* @brief Verify a CVD file by loading and unloading it.
*
* May also verify the CVD digital signature.
* For `.cvd` files, this also verifies the CVD digital signature.
*
* @param file Filepath of CVD file.
* @param certs_directory Directory containing CA certificates required to verify the CVD digital signature.
* @param dboptions Bitmask of flags to modify behavior.
* Set CL_DB_FIPS_LIMITS to require the CVD to be signed with a FIPS-compliant external '.sign' file.
Comment on lines +1962 to 1967
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cl_cvdverify_ex() still supports CL_DB_UNSIGNED (and other APIs in this header document it), but this doc block no longer mentions it. Please restore/update the documentation to reflect that CL_DB_UNSIGNED disables digital signature verification (and clarify how that interacts with the “also verifies signature” statement).

Suggested change
* For `.cvd` files, this also verifies the CVD digital signature.
*
* @param file Filepath of CVD file.
* @param certs_directory Directory containing CA certificates required to verify the CVD digital signature.
* @param dboptions Bitmask of flags to modify behavior.
* Set CL_DB_FIPS_LIMITS to require the CVD to be signed with a FIPS-compliant external '.sign' file.
* For `.cvd` files, this also verifies the CVD digital signature by default.
* Signature verification can be disabled by setting CL_DB_UNSIGNED in @p dboptions.
*
* @param file Filepath of CVD file.
* @param certs_directory Directory containing CA certificates required to verify the CVD digital signature.
* @param dboptions Bitmask of flags to modify behavior.
* Set CL_DB_FIPS_LIMITS to require the CVD to be signed with a FIPS-compliant external '.sign' file.
* Set CL_DB_UNSIGNED to disable digital signature verification, even for `.cvd` files
* (if CL_DB_UNSIGNED is set, no FIPS signature checks are performed).

Copilot uses AI. Check for mistakes.
* Set CL_DB_UNSIGNED to disable verification of CVD digital signatures. Allow load testing unsigned CVD files.
* @return cl_error_t CL_SUCCESS if success, else a CL_E* error code.
*/
extern cl_error_t cl_cvdverify_ex(const char *file, const char *certs_directory, uint32_t dboptions);
Expand Down
10 changes: 7 additions & 3 deletions libclamav/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -709,12 +709,16 @@ extern cl_error_t cl_hash_file_fd_ex(
}

do {
blocksize = MIN(blocksize, length - byte_read);
size_t read_size = blocksize;

if (length != 0) {
read_size = MIN(read_size, length - byte_read);
}

#ifdef _WIN32
nread = _read(fd, block, blocksize);
nread = _read(fd, block, read_size);
#else
nread = read(fd, block, blocksize);
nread = read(fd, block, read_size);
Comment on lines +712 to +721
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Windows, _read() takes an unsigned int byte count, but read_size is size_t. This can trigger warnings / truncation concerns. Consider making read_size an unsigned int under _WIN32 (or casting with an explicit bounds check) so the type matches _read’s signature.

Copilot uses AI. Check for mistakes.
#endif
if (nread < 0) {
cli_errmsg("cl_hash_data_ex: Failed to read from file descriptor %d: %s\n", fd, cl_strerror(CL_EREAD));
Expand Down
6 changes: 3 additions & 3 deletions libclamav/fmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1455,12 +1455,12 @@ extern cl_error_t cl_fmap_get_size(const cl_fmap_t *map, size_t *size_out)
return status;
}

extern cl_error_t cl_fmap_set_hash(const cl_fmap_t *map, const char *hash_alg, char hash)
extern cl_error_t cl_fmap_set_hash(const cl_fmap_t *map, const char *hash_alg, const char *hash)
{
cl_error_t status = CL_ERROR;
cli_hash_type_t type;

if (!map || !hash_alg) {
if (!map || !hash_alg || !hash) {
status = CL_ENULLARG;
Comment on lines +1458 to 1464
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cl_fmap_set_hash() now takes const char *hash, but fmap_set_hash() treats it as a binary digest buffer of length cli_hash_len(type) (not a NUL-terminated string). To avoid ambiguity and make the API self-describing, consider changing the parameter type (and docs) to const uint8_t * (or const void *) and explicitly documenting the required buffer length per algorithm.

Copilot uses AI. Check for mistakes.
goto done;
}
Expand All @@ -1477,7 +1477,7 @@ extern cl_error_t cl_fmap_set_hash(const cl_fmap_t *map, const char *hash_alg, c
goto done;
}

status = fmap_set_hash((fmap_t *)map, (uint8_t *)&hash, type);
status = fmap_set_hash((fmap_t *)map, (uint8_t *)hash, type);
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cast drops const ((uint8_t *)hash) even though the hash buffer is only read (copied via memcpy in fmap_set_hash). Prefer updating fmap_set_hash() to accept const uint8_t * (and/or casting to const uint8_t * in the call) to preserve const-correctness and avoid compiler warnings.

Suggested change
status = fmap_set_hash((fmap_t *)map, (uint8_t *)hash, type);
status = fmap_set_hash((fmap_t *)map, (const uint8_t *)hash, type);

Copilot uses AI. Check for mistakes.
if (status != CL_SUCCESS) {
cli_errmsg("cl_fmap_set_hash: Failed to set hash for algorithm: %s\n", hash_alg);
goto done;
Expand Down
10 changes: 6 additions & 4 deletions libclamav/scanners.c
Original file line number Diff line number Diff line change
Expand Up @@ -3844,7 +3844,7 @@
// First check if actually a GPT, not MBR.
cl_error_t iret = cli_mbr_check2(ctx, 0);

if ((iret == CL_TYPE_GPT) && (DCONF_ARCH & ARCH_CONF_GPT)) {

Check warning on line 3847 in libclamav/scanners.c

View workflow job for this annotation

GitHub Actions / build-windows

operands are different enum types 'cl_error_t' and 'cli_file'; use an explicit cast to silence this warning
// Reassign type of current layer based on what we discovered
if (CL_SUCCESS != (ret = cli_recursion_stack_change_type(ctx, CL_TYPE_GPT, true))) {
cli_dbgmsg("Call to cli_recursion_stack_change_type() returned %s \n", cl_strerror(ret));
Expand Down Expand Up @@ -4145,7 +4145,7 @@
case CL_TYPE_HTML:
if (cli_recursion_stack_get_type(ctx, -2) == CL_TYPE_AUTOIT) {
/* bb#11196 - autoit script file misclassified as HTML */
ret = CL_TYPE_TEXT_ASCII;

Check warning on line 4148 in libclamav/scanners.c

View workflow job for this annotation

GitHub Actions / build-windows

implicit conversion from enum type 'cli_file' to enum type 'cl_error_t'; use an explicit cast to silence this warning
} else if (SCAN_PARSE_HTML &&
(type == CL_TYPE_TEXT_ASCII ||
type == CL_TYPE_GIF) && /* Scan GIFs for embedded HTML/Javascript */
Expand Down Expand Up @@ -6488,11 +6488,12 @@
NULL);

if (NULL != scanned) {
if (SIZEOF_LONG == 4 && scanned_bytes > UINT32_MAX) {
if ((SIZEOF_LONG == 4) &&
(scanned_bytes / CL_COUNT_PRECISION > UINT32_MAX)) {
cli_warnmsg("cl_scanfile_callback: scanned_bytes exceeds UINT32_MAX, setting to UINT32_MAX\n");
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overflow check now compares (scanned_bytes / CL_COUNT_PRECISION) > UINT32_MAX, but the warning message still says scanned_bytes exceeds UINT32_MAX and is tagged cl_scanfile_callback even in cl_scanfile(). Please update the log text to reference the correct function and units (bytes/CL_COUNT_PRECISION) so the warning is accurate and actionable.

Suggested change
cli_warnmsg("cl_scanfile_callback: scanned_bytes exceeds UINT32_MAX, setting to UINT32_MAX\n");
cli_warnmsg("cl_scanfile: scanned_bytes/CL_COUNT_PRECISION exceeds UINT32_MAX, setting scanned to UINT32_MAX\n");

Copilot uses AI. Check for mistakes.
*scanned = UINT32_MAX;
} else {
*scanned = (unsigned long int)scanned_bytes;
*scanned = (unsigned long int)(scanned_bytes / CL_COUNT_PRECISION);
}
}

Expand Down Expand Up @@ -6532,11 +6533,12 @@
NULL);

if (NULL != scanned) {
if (SIZEOF_LONG == 4 && scanned_out > UINT32_MAX) {
if ((SIZEOF_LONG == 4) &&
(scanned_out / CL_COUNT_PRECISION > UINT32_MAX)) {
cli_warnmsg("cl_scanfile_callback: scanned_out exceeds UINT32_MAX, setting to UINT32_MAX\n");
*scanned = UINT32_MAX;
} else {
*scanned = (unsigned long int)scanned_out;
*scanned = (unsigned long int)(scanned_out / CL_COUNT_PRECISION);
}
}

Expand Down
Loading