Skip to content

Commit d5e6d20

Browse files
committed
CMake: fix issue finding openssl include directory for Rust build
Also fix issue when certs directory param for cl_cvdunpack_ex is NULL
1 parent ff84050 commit d5e6d20

12 files changed

Lines changed: 130 additions & 47 deletions

File tree

clamd/clamd.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ int main(int argc, char **argv)
172172
pid_t mainpid = 0;
173173
mode_t old_umask = 0;
174174
const char *user_name = NULL;
175-
char *cvdcertsdir = NULL;
175+
char *cvdcertsdir = NULL;
176176
STATBUF statbuf;
177177

178178
if (check_flevel())
@@ -597,9 +597,9 @@ int main(int argc, char **argv)
597597
// (which would've used the env var or hardcoded path)
598598
if (LSTAT(cvdcertsdir, &statbuf) == -1) {
599599
logg(LOGG_ERROR,
600-
"ClamAV CA certificates directory is missing: %s\n"
601-
"It should have been provided as a part of installation.",
602-
cvdcertsdir);
600+
"ClamAV CA certificates directory is missing: %s\n"
601+
"It should have been provided as a part of installation.",
602+
cvdcertsdir);
603603
ret = 1;
604604
break;
605605
}

clamscan/manager.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,9 +1258,9 @@ int scanmanager(const struct optstruct *opts)
12581258
// (which would've used the env var or hardcoded path)
12591259
if (LSTAT(cvdcertsdir, &statbuf) == -1) {
12601260
logg(LOGG_ERROR,
1261-
"ClamAV CA certificates directory is missing: %s\n"
1262-
"It should have been provided as a part of installation.",
1263-
cvdcertsdir);
1261+
"ClamAV CA certificates directory is missing: %s\n"
1262+
"It should have been provided as a part of installation.",
1263+
cvdcertsdir);
12641264
ret = 2;
12651265
goto done;
12661266
}

libclamav/cvd.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -685,25 +685,33 @@ cl_error_t cl_cvdunpack_ex(const char *file, const char *dir, bool dont_verify,
685685
return CL_EOPEN;
686686
}
687687

688-
if (!dont_verify) {
689-
if (!codesign_verifier_new(certs_directory, &verifier, &new_verifier_error)) {
690-
cli_errmsg("Failed to create a new code-signature verifier: %s\n", ffierror_fmt(new_verifier_error));
688+
if (dont_verify) {
689+
// Just unpack the CVD file.
690+
if (!cvd_unpack(cvd, dir, &cvd_unpack_error)) {
691+
cli_errmsg("CVD unpacking failed: %s\n", ffierror_fmt(cvd_unpack_error));
691692
status = CL_EUNPACK;
692693
goto done;
693694
}
695+
} else {
696+
// Verify the CVD file and hten unpack it.
697+
698+
// The certs directory is optional.
699+
// If not provided, then we can't validate external signatures and will have to rely
700+
// on the internal MD5-based RSA signature.
701+
if (NULL != certs_directory) {
702+
if (!codesign_verifier_new(certs_directory, &verifier, &new_verifier_error)) {
703+
cli_errmsg("Failed to create a new code-signature verifier: %s\n", ffierror_fmt(new_verifier_error));
704+
status = CL_EUNPACK;
705+
goto done;
706+
}
707+
}
694708

695709
status = cli_cvdunpack_and_verify(file, dir, dont_verify, verifier);
696710
if (status != CL_SUCCESS) {
697711
goto done;
698712
}
699713
}
700714

701-
if (!cvd_unpack(cvd, dir, &cvd_unpack_error)) {
702-
cli_errmsg("CVD unpacking failed: %s\n", ffierror_fmt(cvd_unpack_error));
703-
status = CL_EUNPACK;
704-
goto done;
705-
}
706-
707715
done:
708716

709717
if (NULL != signer_name) {

libclamav/others.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ struct cl_engine {
321321
uint32_t ac_mindepth;
322322
uint32_t ac_maxdepth;
323323
char *tmpdir;
324-
char* certs_directory;
324+
char *certs_directory;
325325
uint32_t keeptmp;
326326
uint64_t engine_options;
327327
uint32_t cache_size;

libclamav_rust/CMakeLists.txt

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,39 @@
44
# Copyright (C) 2021-2024 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
55
#
66

7-
# if OPENSSL_ROOT_DIR is set, pass it to the environment
8-
if(OPENSSL_ROOT_DIR)
9-
set(ENVIRONMENT "OPENSSL_DIR=${OPENSSL_ROOT_DIR}")
10-
else ()
11-
set(ENVIRONMENT "")
12-
endif()
7+
get_filename_component(OPENSSL_DIR "${OPENSSL_INCLUDE_DIR}" DIRECTORY)
8+
9+
# The Rust openssl-sys crate needs to know how to find the OpenSSL headers and libraries.
10+
set(OPENSSL_LIBS "")
11+
foreach(LIB IN LISTS OPENSSL_LIBRARIES)
12+
# Skip any libraries starting with `-l` (e.g. -lpthread).
13+
# These are system libraries and won't be found in the OPENSSL_LIB_DIR.
14+
if (NOT LIB MATCHES "^-l")
15+
# Remove path and extension
16+
get_filename_component(LIBNAME "${LIB}" NAME_WLE)
17+
18+
# Remove "lib" prefix, if present
19+
string(REGEX REPLACE "^lib" "" LIBNAME "${LIBNAME}")
20+
21+
if (NOT OPENSSL_LIBS)
22+
# Add first openssl lib.
23+
set(OPENSSL_LIBS "${LIBNAME}")
24+
25+
# While we're at it... get directory of the first library to use for the OPENSSL_LIB_DIR.
26+
# Note: This assumes that all libs are in the same directory.
27+
get_filename_component(OPENSSL_LIB_DIR "${LIB}" DIRECTORY)
28+
else()
29+
# Add additional openssl libs.
30+
set(OPENSSL_LIBS "${OPENSSL_LIBS}:${LIBNAME}")
31+
endif()
32+
endif()
33+
endforeach()
34+
35+
set(ENVIRONMENT "")
36+
list(APPEND ENVIRONMENT "OPENSSL_DIR=${OPENSSL_DIR}")
37+
list(APPEND ENVIRONMENT "OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR}")
38+
list(APPEND ENVIRONMENT "OPENSSL_LIBS=${OPENSSL_LIBS}")
39+
list(APPEND ENVIRONMENT "OPENSSL_LIB_DIR=${OPENSSL_LIB_DIR}")
1340

1441
# libclamav rust static library
1542
add_rust_library(TARGET clamav_rust

libclamav_rust/build.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,13 @@ const BINDGEN_FUNCTIONS: &[&str] = &[
6060
];
6161

6262
// Generate bindings for these types (structs, enums):
63-
const BINDGEN_TYPES: &[&str] = &["cli_matcher", "cli_ac_data", "cli_ac_result", "onedump_t", "cvd_t"];
63+
const BINDGEN_TYPES: &[&str] = &[
64+
"cli_matcher",
65+
"cli_ac_data",
66+
"cli_ac_result",
67+
"onedump_t",
68+
"cvd_t",
69+
];
6470

6571
// Find the required functions and types in these headers:
6672
const BINDGEN_HEADERS: &[&str] = &[

libclamav_rust/src/cdiff.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,15 @@
1919
*/
2020

2121
use std::{
22-
collections::BTreeMap, ffi::{c_void, CStr, CString}, fs::{self, File, OpenOptions}, io::{prelude::*, BufReader, BufWriter, Read, Seek, SeekFrom, Write}, iter::*, mem::ManuallyDrop, os::raw::c_char, path::{Path, PathBuf}, str::{self, FromStr}
22+
collections::BTreeMap,
23+
ffi::{c_void, CStr, CString},
24+
fs::{self, File, OpenOptions},
25+
io::{prelude::*, BufReader, BufWriter, Read, Seek, SeekFrom, Write},
26+
iter::*,
27+
mem::ManuallyDrop,
28+
os::raw::c_char,
29+
path::{Path, PathBuf},
30+
str::{self, FromStr},
2331
};
2432

2533
use crate::{

libclamav_rust/src/cvd.rs

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,18 @@ use std::{
2323
fs::File,
2424
io::{prelude::*, BufReader},
2525
mem::ManuallyDrop,
26-
os::{
27-
fd::AsRawFd,
28-
raw::{c_char, c_void},
29-
},
26+
os::raw::{c_char, c_void},
3027
path::{Path, PathBuf},
3128
str::FromStr,
3229
time::{Duration, SystemTime},
3330
};
3431

32+
#[cfg(any(unix))]
33+
use std::os::fd::AsRawFd;
34+
35+
#[cfg(any(windows))]
36+
use std::os::windows::io::{AsRawHandle, RawHandle};
37+
3538
use crate::codesign::Verifier;
3639
use flate2::read::GzDecoder;
3740
use hex;
@@ -647,16 +650,29 @@ pub unsafe extern "C" fn cvd_verify(
647650
) -> bool {
648651
let mut cvd = ManuallyDrop::new(Box::from_raw(cvd as *mut CVD));
649652

650-
let verifier = ManuallyDrop::new(Box::from_raw(verifier_ptr as *mut Verifier));
651-
652-
match cvd.verify(Some(&verifier), disable_md5) {
653-
Ok(signer) => {
654-
let signer_cstr = std::ffi::CString::new(signer).unwrap();
655-
*signer_name = signer_cstr.into_raw();
656-
true
653+
if verifier_ptr.is_null() {
654+
match cvd.verify(None, disable_md5) {
655+
Ok(signer) => {
656+
let signer_cstr = std::ffi::CString::new(signer).unwrap();
657+
*signer_name = signer_cstr.into_raw();
658+
true
659+
}
660+
Err(e) => {
661+
ffi_error!(err = err, e)
662+
}
657663
}
658-
Err(e) => {
659-
ffi_error!(err = err, e)
664+
} else {
665+
let verifier = ManuallyDrop::new(Box::from_raw(verifier_ptr as *mut Verifier));
666+
667+
match cvd.verify(Some(&verifier), disable_md5) {
668+
Ok(signer) => {
669+
let signer_cstr = std::ffi::CString::new(signer).unwrap();
670+
*signer_name = signer_cstr.into_raw();
671+
true
672+
}
673+
Err(e) => {
674+
ffi_error!(err = err, e)
675+
}
660676
}
661677
}
662678
}
@@ -778,8 +794,29 @@ pub unsafe extern "C" fn cvd_get_builder(cvd: *const c_void) -> *mut c_char {
778794
///
779795
/// No parameters may be NULL
780796
/// The CVD pointer must be valid
797+
#[cfg(any(unix))]
781798
#[export_name = "cvd_get_file"]
782799
pub unsafe extern "C" fn cvd_get_file(cvd: *const c_void) -> i32 {
783800
let cvd = ManuallyDrop::new(Box::from_raw(cvd as *mut CVD));
801+
784802
cvd.file.as_raw_fd()
785803
}
804+
805+
/// C interface for getting the file handle of a CVD.
806+
/// Handles all the unsafe ffi stuff.
807+
/// Returns the file handle an integer.
808+
/// The caller must not close the file handle.
809+
/// The file handle is not guaranteed to be valid after the CVD struct is freed.
810+
///
811+
/// # Safety
812+
///
813+
/// No parameters may be NULL
814+
/// The CVD pointer must be valid
815+
#[cfg(any(windows))]
816+
#[export_name = "cvd_get_file"]
817+
pub unsafe extern "C" fn cvd_get_file(cvd: *const c_void) -> i32 {
818+
let cvd = ManuallyDrop::new(Box::from_raw(cvd as *mut CVD));
819+
820+
let file = cvd.file.as_raw_handle();
821+
file.to_fd()
822+
}

libclamav_rust/src/ffi_util.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use std::{
2626
os::raw::c_char,
2727
};
2828

29-
use log::{warn};
29+
use log::warn;
3030

3131
/// Wraps a call to a "result-returning function", allowing it to specify an
3232
/// error receiver and (optionally) result receiver.
@@ -426,7 +426,7 @@ macro_rules! validate_str_param_null {
426426
///
427427
/// The CString pointer must be valid
428428
/// The CString pointer must not be used after calling this function
429-
#[export_name = "ffi_cstring_free"]
429+
#[export_name = "ffi_cstring_free"]
430430
pub unsafe extern "C" fn ffi_cstring_free(cstring: *mut c_char) {
431431
if cstring.is_null() {
432432
warn!("Attempted to free a NULL CString pointer. Please report this at:: https://github.com/Cisco-Talos/clamav/issues");

libclamav_rust/src/fuzzy_hash.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ pub unsafe extern "C" fn _fuzzy_hash_load_subsignature(
181181
subsig_id: u32,
182182
err: *mut *mut FFIError,
183183
) -> bool {
184-
let hexsig = validate_str_param!(hexsig, err=err);
184+
let hexsig = validate_str_param!(hexsig, err = err);
185185

186186
let mut hashmap = ManuallyDrop::new(Box::from_raw(fuzzy_hashmap as *mut FuzzyHashMap));
187187

0 commit comments

Comments
 (0)