From 9d767e527112fb56be2a6a68d395b9e7a8588813 Mon Sep 17 00:00:00 2001 From: SutekhVRC Date: Tue, 18 Jun 2024 23:24:07 -0700 Subject: [PATCH] - parse_osc() memory corruption fixes - Fix invalid pointer caused by invalid packet. - Handle errors for extract_osc_value and extract_osc_address Important Note: The following code was fuzzed with a few assumptions. - The input buffer is always 4096 bytes - The index passed is always 0 Ignoring these assumptions leads to many memory corruption bugs including: - Off-By-N - OBR --- src/lib.rs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4879ce9..c244fdc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,9 @@ use std::ffi::{c_char, c_uchar, CStr, CString}; use std::ptr::null; -use std::{slice}; +use std::slice; use std::time::{SystemTime, UNIX_EPOCH}; + macro_rules! println { ($($arg:tt)*) => ({ #[cfg(debug_assertions)] @@ -169,7 +170,9 @@ fn parse(buf: &[u8], index: &mut usize) -> Result { return Err(ParserError::InvalidFormat); } - let address = extract_osc_address(&buf, index); + let Ok(address) = extract_osc_address(&buf, index) else { + return Err(ParserError::InvalidAddress); + }; println!("Address: {:?}", address); // Ensure we still have data @@ -177,24 +180,21 @@ fn parse(buf: &[u8], index: &mut usize) -> Result { return Err(ParserError::InvalidFormat); } - let value = extract_osc_values(&buf, index); + let Ok(value) = extract_osc_values(&buf, index) else { + return Err(ParserError::InvalidValue); + }; println!("Value: {:?}", value); - return match (address, value) { - (Ok(address), Ok(value)) => { - Ok(OscMessage { - address: CString::new(address).unwrap().into_raw(), - value_length: value.len() as i32, - value: Box::into_raw(value.into_boxed_slice()) as *const OscValue, - }) - } - (Err(e), _) => { - Err(e) - } - (_, Err(e)) => { - Err(e) - } - }; + if value.is_empty() { + return Err(ParserError::InvalidValue); + } + + Ok(OscMessage { + address: CString::new(address).unwrap().into_raw(), + value_length: value.len() as i32, + value: Box::into_raw(value.into_boxed_slice()) as *const OscValue, + }) + } // Import a byte array from C# and parse it