detect/transforms: decompress checks earlier if it is in-place

Ticket: 8536

Otherwise, it may cause a use-after-free.

So, need to allocate the temporary vector, before calling
SCInspectionBufferCheckAndExpand

(cherry picked from commit 2b20a436e7)
pull/15433/head
Philippe Antoine 2 months ago committed by Victor Julien
parent 4253b82db7
commit 11d1fe1ca8

@ -20,8 +20,8 @@ use crate::detect::SIGMATCH_OPTIONAL_OPT;
use flate2::bufread::{GzDecoder, ZlibDecoder};
use suricata_sys::sys::{
DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister,
SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferTruncate,
SCTransformTableElmt, Signature,
SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferInPlace,
SCInspectionBufferTruncate, SCTransformTableElmt, Signature,
};
use std::ffi::CStr;
@ -132,26 +132,27 @@ unsafe fn decompress_transform(
if input.is_null() || input_len == 0 {
return;
}
let input = build_slice!(input, input_len as usize);
let tmp;
let slice_input = if SCInspectionBufferInPlace(buffer) {
// need a temporary buffer as we cannot do the transfom in place
// rather copy the input which should be smaller than the decompressed output
// (Transform is tried in place when there are multiple chained transforms)
// needs to happen before possible realloc in SCInspectionBufferCheckAndExpand
tmp = build_slice!(input, input_len as usize).to_vec();
&tmp
} else {
build_slice!(input, input_len as usize)
};
let output = SCInspectionBufferCheckAndExpand(buffer, ctx.max_size);
if output.is_null() {
// allocation failure
return;
}
let buf = std::slice::from_raw_parts_mut(output, ctx.max_size as usize);
let mut tmp = Vec::new();
let input = if std::ptr::eq(output, input.as_ptr()) {
// need a temporary buffer as we cannot do the transfom in place
// rather copy the input which should be smaller than the decompressed output
// (Transform is tried in place when there are multiple chaines transforms)
tmp.extend_from_slice(input);
&tmp
} else {
input
};
// this succeeds if decompressed data > max_size, but we get nb = max_size
if let Some(nb) = decompress_fn(input, buf) {
if let Some(nb) = decompress_fn(slice_input, buf) {
SCInspectionBufferTruncate(buffer, nb);
} else {
// decompression failure

Loading…
Cancel
Save