-
-
Notifications
You must be signed in to change notification settings - Fork 324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Input Types and Mutators for Numeric Types #2760
Conversation
* Rules * more * aa
* fixing empty multipart name * fixing clippy * improve flexibility of DumpToDiskStage * adding note to MIGRATION.md
Turns out Rust has some built-in functionality I did not know about. |
Let me figure out mapping for these as well. |
Thoughts? |
Left some more comments (sorry :D) Also, it probably makes sense to support an "interesting values" mutator(?) LibAFL/libafl/src/mutators/mutations.rs Line 95 in be21fae
Note that stacking mutations probably makes a lot less sense for int mutations btw, no clue how to best model that. |
Thank you for your time!
Ideally, you'd want to statically generate them at this point, otherwise you'll create a lot of duplicate code. Maybe I'll get around to it at some point. Create an issue and merge this for now?
Fair enough, but I'm not sure you'd ever use this outside of mapped mutators anyways, and there stacking makes sense again, so 🤷♂️. |
libafl/src/inputs/value.rs
Outdated
use super::{ValueInput, ValueMutRefInput}; | ||
use crate::mutators::numeric::Numeric; | ||
|
||
fn take_numeric<I: Numeric + Clone>(i: I) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this supposed to test? I wouldn't be at all surprised if the compiler notices that this is all dead code and optimizes it away. Perhaps this should assert_eq!
that i.clone.f()
is the same as ValueInput::from(i.clone()).f().inner()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Valid point, this definitely is not a robust testing regime.
To be honest, this was mostly a test during development that the types work out, so the fact that it compiles is the main testing success.
Previous implementations panicked on certain values, and especially min and max values seemed unstable. I don't think this is still possible, but I figured the cost of leaving this here is minimal compared to potential breakage.
Ideally however, we'd prove some of these properties, I have no idea how to do this though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have renamed the test to better reflect what it's currently doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm now also checking if the operations actually change the values. Still not comprehensive, but it's a start.
libafl/src/mutators/numeric.rs
Outdated
|
||
/// Flip the bit at the specified offset. | ||
/// | ||
/// Has no effect if `offset` is out of bounds for the type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems inconsistent with the impl
below, <<
panics if the RHS is too big (playground)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I have added a safety notice. Is that enough?
libafl/src/mutators/numeric.rs
Outdated
fn randomize<R: Rand>(&mut self, rand: &mut R) { | ||
// flip random bits, no need to reset to zero | ||
*self ^= <$t>::from(rand.next()); | ||
*self ^= <$t>::from(rand.next()) << 64; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be done on values >64 bit. It's useless overhead on anything else
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like, since rand.next()
changes the state, it has to be executed even though the value is ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The macro is only called for u128
and i128
, I have another implementation with a straight cast for the other types:
*self = rand.next() as $t;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aaah missed that, nice! <3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be something like:
*self = (((rand.next() as u128 << 64)) | rand.next() as u128) as $t
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind that guy isn't optimized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*self ^= <$t>::from(rand.next()) << 64 | <$t>::from(rand.next());
This produces the same output, but clippy doesn't complain about infallible casts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why xor? Just assign
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The casts are all right, fwiw. But I'm fine with either. Shifting in unsigned land is in generally less ... weird.. though, that's why I prefer it. play it safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough.
Thanks! |
* fixing empty multipart name * fixing clippy * New rules for the contributing (AFLplusplus#2752) * Rules * more * aa * Improve Flexibility of DumpToDiskStage (AFLplusplus#2753) * fixing empty multipart name * fixing clippy * improve flexibility of DumpToDiskStage * adding note to MIGRATION.md * Introduce WrappingMutator * introducing mutators for int types * fixing no_std * random fixes * Add hash derivation for WrappingInput * Revert fixes that broke things * Derive Default on WrappingInput * Add unit tests * Fixes according to code review * introduce mappable ValueInputs * remove unnecessary comments * Elide more lifetimes * remove dead code * simplify hashing * improve docs * improve randomization * rename method to align with standard library * add typedefs for int types for ValueMutRefInput * rename test * add safety notice to trait function * improve randomize performance for i128/u128 * rename macro * improve comment * actually check return values in test * make 128 bit int randomize even more efficient * shifting signed values --------- Co-authored-by: Dongjia "toka" Zhang <[email protected]> Co-authored-by: Dominik Maier <[email protected]>
No description provided.