fix(AflppRedQueen): fix u64 I2S mutation and allow variable-length FnOperands#3741
fix(AflppRedQueen): fix u64 I2S mutation and allow variable-length FnOperands#3741drewbarbs wants to merge 2 commits intoAFLplusplus:mainfrom
Conversation
960e2e0 to
0fecd57
Compare
|
awesome awesome awesome, I've been wanting this for a while. I'll give this a review once we've repaired the CI and you can once again rebase. |
|
@addisoncrump Ci is green, can you take a look? |
addisoncrump
left a comment
There was a problem hiding this comment.
Some cleaning changes that should be done instead of the bug fix provided, since this was a code-copying error.
| cloned[buf_idx] = ((repl >> 48) & 0xff) as u8; | ||
| cloned[buf_idx + 2] = ((repl >> 40) & 0xff) as u8; | ||
| cloned[buf_idx + 1] = ((repl >> 48) & 0xff) as u8; | ||
| cloned[buf_idx] = ((repl >> 56) & 0xff) as u8; |
There was a problem hiding this comment.
This looks like something that should get replaced by cloned[buf_idx..(buf_idx+8)].copy_from_slice(&repl.to_bytes_le()[..8]).
When the RQ mutator sees that a 8 byte comparison operand is equal to 8 bytes from the input, then it treats that as an I2S correspondence and pushes a mutation that replaces those input bytes with a big-endian encoding of the second comparison operand, `repl` (this process is done on both the original/byte-swapped versions of the relevant values, to handle either byte order) This commit fixes a bit shifting bug (probably typo) that broke the replacement and made RQ unable to solve the comparison. Instead, we'll use copy_from_slice
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`.
addisoncrump
left a comment
There was a problem hiding this comment.
Looks good. Do we have a good testbench for this?
|
Yeah I'd been using a tiny C target with an |
|
Please do, thanks :) |
Description
These are a couple of small fixes to the Aflpp RedQueen implementation:
fix AflppRedQueen mutator's u64 I2S replacement
When the RQ mutator sees that a 8 byte comparison operand is equal to 8 bytes from the input, then it treats that as an I2S correspondence and pushes a mutation that replaces those input bytes with a big-endian encoding of the second comparison operand,
repl(this process is done on both the original/byte-swapped versions of the relevant values, to handle either byte order)This commit fixes a bit shifting bug (probably typo) that breaks the replacement by repeating one byte and dropping the most significant byte, which makes RQ unable to solve the comparison.
fix
AflppCmpLogFnOperands::newto allow v0/v1 with different lengthsAflppCmpLogFnOperands has fixed length (
[u8; 32]) storage forv0andv1, and separatev0_len/v1_lenfields. However, the rust constructor/setters only allow forv0/v1to be initialized from slices that are exactly 32 bytes long, sincecopy_from_slicepanics otherwise. Sov0_len/v1_lencan only be 32. The instrumentation inlibafl_targets'cmplog.{h,c}can create log entries where thev0_len/v1_lenvalues are anywhere between 0 and 32, and this change allows us to do the same from rust.Note: in AFLplusplus's cmplog instrumentation,
v0_len/v1_lenare always the same value. In AFLplusplus' implementation,__cmplog_rtn_hook_strcan create log entries withv0_len != v1_len, which this change also allows.Checklist
./scripts/precommit.shand addressed all comments