Skip to content

Commit ce33aec

Browse files
committed
fix AflppCmpLogFnOperands::new to allow v0/v1 with different lengths
AflppCmpLogFnOperands has fixed length (`[u8; 32]`) storage for `v0` and `v1`, and separate `v0_len`/`v1_len` fields. However, the rust constructor/setters only allow for `v0`/`v1` to be initialized from slices that are _exactly_ 32 bytes long, since `copy_from_slice` panics otherwise. So `v0_len`/`v1_len` can only be 32. The instrumentation in `libafl_targets`' `cmplog.{h,c}` can create log entries where the `v0_len`/`v1_len` values are anywhere between 0 and 32, so this change allows us to do the same from rust. Note: in LibAFL's cmplog instrumentation, `v0_len`/`v1_len` are always _the same_ value. In AFLplusplus' implementation, `__cmplog_rtn_hook_str` can create log entries with `v0_len != v1_len`.
1 parent e75d518 commit ce33aec

1 file changed

Lines changed: 16 additions & 14 deletions

File tree

  • crates/libafl_targets/src/cmps

crates/libafl_targets/src/cmps/mod.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,8 @@ impl AflppCmpLogOperands {
224224
#[repr(C, packed)]
225225
/// Comparison function operands, like for strcmp/memcmp, represented as two byte arrays.
226226
pub struct AflppCmpLogFnOperands {
227-
v0: [u8; 32],
228-
v1: [u8; 32],
227+
v0: [u8; CMPLOG_RTN_LEN],
228+
v1: [u8; CMPLOG_RTN_LEN],
229229
v0_len: u8,
230230
v1_len: u8,
231231
unused: [u8; 6],
@@ -235,14 +235,16 @@ impl AflppCmpLogFnOperands {
235235
#[must_use]
236236
/// Create a new AFL++ function operands comparison values from two byte slices
237237
pub fn new(v0: &[u8], v1: &[u8]) -> Self {
238-
let v0_len = v0.len() as u8;
239-
let v1_len = v1.len() as u8;
238+
let v0_len = v0.len().min(CMPLOG_RTN_LEN) as u8;
239+
let v0_truncated = &v0[..v0_len as usize];
240+
let v1_len = v1.len().min(CMPLOG_RTN_LEN) as u8;
241+
let v1_truncated = &v1[..v1_len as usize];
240242

241-
let mut v0_arr = [0; 32];
242-
let mut v1_arr = [0; 32];
243+
let mut v0_arr = [0; CMPLOG_RTN_LEN];
244+
let mut v1_arr = [0; CMPLOG_RTN_LEN];
243245

244-
v0_arr.copy_from_slice(v0);
245-
v1_arr.copy_from_slice(v1);
246+
v0_arr[..v0_len as usize].copy_from_slice(v0_truncated);
247+
v1_arr[..v1_len as usize].copy_from_slice(v1_truncated);
246248

247249
Self {
248250
v0: v0_arr,
@@ -255,7 +257,7 @@ impl AflppCmpLogFnOperands {
255257

256258
#[must_use]
257259
/// first rtn operand
258-
pub fn v0(&self) -> &[u8; 32] {
260+
pub fn v0(&self) -> &[u8; CMPLOG_RTN_LEN] {
259261
&self.v0
260262
}
261263

@@ -267,7 +269,7 @@ impl AflppCmpLogFnOperands {
267269

268270
#[must_use]
269271
/// first rtn operand len
270-
pub fn v1(&self) -> &[u8; 32] {
272+
pub fn v1(&self) -> &[u8; CMPLOG_RTN_LEN] {
271273
&self.v1
272274
}
273275

@@ -279,14 +281,14 @@ impl AflppCmpLogFnOperands {
279281

280282
/// Set the v0 (left) side of the comparison
281283
pub fn set_v0(&mut self, v0: &[u8]) {
282-
self.v0_len = v0.len() as u8;
283-
self.v0.copy_from_slice(v0);
284+
self.v0_len = v0.len().min(CMPLOG_RTN_LEN) as u8;
285+
self.v0[..self.v0_len as usize].copy_from_slice(&v0[..self.v0_len as usize]);
284286
}
285287

286288
/// Set the v1 (right) side of the comparison
287289
pub fn set_v1(&mut self, v1: &[u8]) {
288-
self.v1_len = v1.len() as u8;
289-
self.v1.copy_from_slice(v1);
290+
self.v1_len = v1.len().min(CMPLOG_RTN_LEN) as u8;
291+
self.v1[..self.v1_len as usize].copy_from_slice(&v1[..self.v1_len as usize]);
290292
}
291293
}
292294

0 commit comments

Comments
 (0)