transform: fix identity function for base64 xfrom

As SCDetectTransformFromBase64Data is not a flat structure,
because it has pointers to other buffers, we cannot use it simply
for TransformId

We need to compute a serialization of the data hold by
SCDetectTransformFromBase64Data and own it.
pull/13356/head
Philippe Antoine 1 year ago committed by Victor Julien
parent 278a9c3806
commit f4a5b741ce

@ -47,11 +47,22 @@ pub struct SCDetectTransformFromBase64Data {
offset: u32,
offset_str: *const c_char,
mode: SCBase64Mode,
// serialized data for hashing
serialized: *const u8,
serialized_len: u32,
}
impl Drop for SCDetectTransformFromBase64Data {
fn drop(&mut self) {
unsafe {
if !self.serialized.is_null() {
drop(Vec::from_raw_parts(
self.serialized as *mut u8,
self.serialized_len as usize,
self.serialized_len as usize,
));
}
if !self.offset_str.is_null() {
let _ = CString::from_raw(self.offset_str as *mut c_char);
}
@ -70,6 +81,8 @@ impl Default for SCDetectTransformFromBase64Data {
offset: 0,
offset_str: std::ptr::null_mut(),
mode: TRANSFORM_FROM_BASE64_MODE_DEFAULT,
serialized: std::ptr::null_mut(),
serialized_len: 0,
}
}
}
@ -80,6 +93,22 @@ impl SCDetectTransformFromBase64Data {
..Default::default()
}
}
pub fn serialize(&mut self, nbytes: &str, offset: &str) {
let mut r = Vec::with_capacity(12 + nbytes.len() + offset.len());
r.push(self.flags);
r.push(self.mode as u8);
r.extend_from_slice(&self.nbytes.to_le_bytes());
r.extend_from_slice(&self.offset.to_le_bytes());
r.push(nbytes.len() as u8);
r.extend_from_slice(nbytes.as_bytes());
r.push(offset.len() as u8);
r.extend_from_slice(offset.as_bytes());
self.serialized_len = r.len() as u32;
let ptr = r.as_mut_ptr();
std::mem::forget(r);
self.serialized = ptr;
}
}
fn get_mode_value(value: &str) -> Option<SCBase64Mode> {
@ -117,6 +146,8 @@ fn parse_transform_base64(
DETECT_TRANSFORM_BASE64_MAX_PARAM_COUNT, input)));
}
let mut nbytes_str = String::new();
let mut offset_str = String::new();
for value in values {
let (mut val, mut name) = take_until_whitespace(value)?;
val = val.trim();
@ -152,17 +183,10 @@ fn parse_transform_base64(
)));
}
}
ResultValue::String(val) => match CString::new(val) {
Ok(newval) => {
transform_base64.offset_str = newval.into_raw();
transform_base64.flags |= DETECT_TRANSFORM_BASE64_FLAG_OFFSET_VAR;
}
_ => {
return Err(make_error(
"parse string not safely convertible to C".to_string(),
))
}
},
ResultValue::String(val) => {
offset_str = val.clone();
transform_base64.flags |= DETECT_TRANSFORM_BASE64_FLAG_OFFSET_VAR;
}
}
transform_base64.flags |= DETECT_TRANSFORM_BASE64_FLAG_OFFSET;
@ -186,17 +210,10 @@ fn parse_transform_base64(
)));
}
}
ResultValue::String(val) => match CString::new(val) {
Ok(newval) => {
transform_base64.nbytes_str = newval.into_raw();
transform_base64.flags |= DETECT_TRANSFORM_BASE64_FLAG_NBYTES_VAR;
}
_ => {
return Err(make_error(
"parse string not safely convertible to C".to_string(),
))
}
},
ResultValue::String(val) => {
nbytes_str = val.clone();
transform_base64.flags |= DETECT_TRANSFORM_BASE64_FLAG_NBYTES_VAR;
}
}
transform_base64.flags |= DETECT_TRANSFORM_BASE64_FLAG_NBYTES;
}
@ -206,6 +223,25 @@ fn parse_transform_base64(
};
}
transform_base64.serialize(&nbytes_str, &offset_str);
if (transform_base64.flags & DETECT_TRANSFORM_BASE64_FLAG_NBYTES_VAR) != 0 {
if let Ok(newval) = CString::new(nbytes_str) {
transform_base64.nbytes_str = newval.into_raw();
} else {
return Err(make_error(
"parse string not safely convertible to C".to_string(),
));
}
}
if (transform_base64.flags & DETECT_TRANSFORM_BASE64_FLAG_OFFSET_VAR) != 0 {
if let Ok(newval) = CString::new(offset_str) {
transform_base64.offset_str = newval.into_raw();
} else {
return Err(make_error(
"parse string not safely convertible to C".to_string(),
));
}
}
Ok((input, transform_base64))
}
@ -283,6 +319,8 @@ mod tests {
std::ptr::null_mut()
},
mode,
serialized: std::ptr::null_mut(),
serialized_len: 0,
};
let (_, val) = parse_transform_base64(args).unwrap();

@ -46,11 +46,8 @@ static void DetectTransformFromBase64Id(const uint8_t **data, uint32_t *length,
{
if (context) {
SCDetectTransformFromBase64Data *b64d = (SCDetectTransformFromBase64Data *)context;
/* Since the context structure contains the unique values for the keyword usage,
* a pointer to the context structure is returned.
*/
*data = (const uint8_t *)b64d;
*length = sizeof(*b64d);
*data = b64d->serialized;
*length = b64d->serialized_len;
}
}

Loading…
Cancel
Save