Skip to content

Commit

Permalink
Fix issue when certs directory param for cl_cvdunpack_ex is NULL
Browse files Browse the repository at this point in the history
  • Loading branch information
micahsnyder committed Jan 16, 2025
1 parent 70d078d commit ecb0010
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 25 deletions.
29 changes: 18 additions & 11 deletions libclamav/cvd.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,7 @@ struct cl_cvd *cl_cvdhead(const char *file)
if ((pt = strpbrk(head, "\n\r")))
*pt = 0;

for (i = bread - 1; i > 0 && (head[i] == ' ' || head[i] == '\n' || head[i] == '\r'); head[i] = 0, i--)
;
for (i = bread - 1; i > 0 && (head[i] == ' ' || head[i] == '\n' || head[i] == '\r'); head[i] = 0, i--);

return cl_cvdparse(head);
}
Expand Down Expand Up @@ -686,25 +685,33 @@ cl_error_t cl_cvdunpack_ex(const char *file, const char *dir, bool dont_verify,
return CL_EOPEN;
}

if (!dont_verify) {
if (!codesign_verifier_new(certs_directory, &verifier, &new_verifier_error)) {
cli_errmsg("Failed to create a new code-signature verifier: %s\n", ffierror_fmt(new_verifier_error));
if (dont_verify) {
// Just unpack the CVD file.
if (!cvd_unpack(cvd, dir, &cvd_unpack_error)) {
cli_errmsg("CVD unpacking failed: %s\n", ffierror_fmt(cvd_unpack_error));
status = CL_EUNPACK;
goto done;
}
} else {
// Verify the CVD file and hten unpack it.

// The certs directory is optional.
// If not provided, then we can't validate external signatures and will have to rely
// on the internal MD5-based RSA signature.
if (NULL != certs_directory) {
if (!codesign_verifier_new(certs_directory, &verifier, &new_verifier_error)) {
cli_errmsg("Failed to create a new code-signature verifier: %s\n", ffierror_fmt(new_verifier_error));
status = CL_EUNPACK;
goto done;
}
}

status = cli_cvdunpack_and_verify(file, dir, dont_verify, verifier);
if (status != CL_SUCCESS) {
goto done;
}
}

if (!cvd_unpack(cvd, dir, &cvd_unpack_error)) {
cli_errmsg("CVD unpacking failed: %s\n", ffierror_fmt(cvd_unpack_error));
status = CL_EUNPACK;
goto done;
}

done:

if (NULL != signer_name) {
Expand Down
5 changes: 4 additions & 1 deletion libclamav_rust/src/codesign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ use clam_sigutil::{

use log::{debug, error, warn};

use crate::{ffi_error, ffi_util::FFIError, sys::cl_retflevel, validate_str_param};
use crate::{
ffi_error, ffi_util::FFIError, sys::cl_retflevel, validate_optional_str_param,
validate_str_param,
};

#[derive(Debug, thiserror::Error)]
pub enum Error {
Expand Down
63 changes: 50 additions & 13 deletions libclamav_rust/src/cvd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ use std::{
fs::File,
io::{prelude::*, BufReader},
mem::ManuallyDrop,
os::{
fd::AsRawFd,
raw::{c_char, c_void},
},
os::raw::{c_char, c_void},
path::{Path, PathBuf},
str::FromStr,
time::{Duration, SystemTime},
};

#[cfg(any(unix))]
use std::os::fd::{AsRawFd, RawFd};

#[cfg(any(windows))]
use std::os::windows::io::{AsRawHandle, RawHandle};

use crate::codesign::Verifier;
use flate2::read::GzDecoder;
use hex;
Expand Down Expand Up @@ -647,16 +650,29 @@ pub unsafe extern "C" fn cvd_verify(
) -> bool {
let mut cvd = ManuallyDrop::new(Box::from_raw(cvd as *mut CVD));

let verifier = ManuallyDrop::new(Box::from_raw(verifier_ptr as *mut Verifier));

match cvd.verify(Some(&verifier), disable_md5) {
Ok(signer) => {
let signer_cstr = std::ffi::CString::new(signer).unwrap();
*signer_name = signer_cstr.into_raw();
true
if verifier_ptr.is_null() {
match cvd.verify(None, disable_md5) {
Ok(signer) => {
let signer_cstr = std::ffi::CString::new(signer).unwrap();
*signer_name = signer_cstr.into_raw();
true
}
Err(e) => {
ffi_error!(err = err, e)
}
}
Err(e) => {
ffi_error!(err = err, e)
} else {
let verifier = ManuallyDrop::new(Box::from_raw(verifier_ptr as *mut Verifier));

match cvd.verify(Some(&verifier), disable_md5) {
Ok(signer) => {
let signer_cstr = std::ffi::CString::new(signer).unwrap();
*signer_name = signer_cstr.into_raw();
true
}
Err(e) => {
ffi_error!(err = err, e)
}
}
}
}
Expand Down Expand Up @@ -778,8 +794,29 @@ pub unsafe extern "C" fn cvd_get_builder(cvd: *const c_void) -> *mut c_char {
///
/// No parameters may be NULL
/// The CVD pointer must be valid
#[cfg(any(unix))]
#[export_name = "cvd_get_file"]
pub unsafe extern "C" fn cvd_get_file(cvd: *const c_void) -> i32 {
let cvd = ManuallyDrop::new(Box::from_raw(cvd as *mut CVD));

cvd.file.as_raw_fd()
}

/// C interface for getting the file handle of a CVD.
/// Handles all the unsafe ffi stuff.
/// Returns the file handle an integer.
/// The caller must not close the file handle.
/// The file handle is not guaranteed to be valid after the CVD struct is freed.
///
/// # Safety
///
/// No parameters may be NULL
/// The CVD pointer must be valid
#[cfg(any(windows))]
#[export_name = "cvd_get_file"]
pub unsafe extern "C" fn cvd_get_file(cvd: *const c_void) -> i32 {
let cvd = ManuallyDrop::new(Box::from_raw(cvd as *mut CVD));

let file = cvd.file.as_raw_handle();
file.to_fd()
}

0 comments on commit ecb0010

Please sign in to comment.