-
-
Notifications
You must be signed in to change notification settings - Fork 330
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
Use const
to Inform CmpLog Replacements
#2528
Conversation
looks great 👍 |
libafl_targets/src/cmplog.h
Outdated
@@ -152,6 +155,7 @@ static inline void cmplog_instructions_extended_checked( | |||
hits &= CMPLOG_MAP_H - 1; | |||
libafl_cmplog_map_extended_ptr->vals.operands[k][hits].v0 = arg1; | |||
libafl_cmplog_map_extended_ptr->vals.operands[k][hits].v1 = arg2; | |||
libafl_cmplog_map_extended_ptr->vals.operands[k][hits].v0_is_const = 0; |
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 "extended" one is only used for llvm pass instrumentation (which is not using sancov stuff so you don't add it for this.
(but it's doable to add the const checking logic to the llvm pass
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.
line 222, too
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.
Yeah, hence it is set to 0
for now (unless you wanted to create a separate CmpLog
struct without the v0_is_const
member). I think that for longer comparisons (such as u64 or memcmps), the chance of conincidentally matching a const value is lower (apart from values like 0
); so it's probably not worth the extra effort.
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 i mean is struct CmpLogInstructionExtended
doesn't have v0_is_const member
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.
True
libafl_targets/src/cmplog.h
Outdated
@@ -186,6 +190,7 @@ static inline void cmplog_routines_checked(uintptr_t k, const uint8_t *ptr1, | |||
hits &= CMPLOG_MAP_RTN_H - 1; | |||
MEMCPY(libafl_cmplog_map_ptr->vals.routines[k][hits].v0, ptr1, len); | |||
MEMCPY(libafl_cmplog_map_ptr->vals.routines[k][hits].v1, ptr2, len); | |||
libafl_cmplog_map_ptr->vals.operands[k][hits].v0_is_const = 0; |
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 callback is for routines. you don't need it here
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.
Again, this is basically an unused struct member - I still think it's worth making sure that it's initialised, even if it is always 0.
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.
hmm but this is a union. so you shouldn't be touching operand side of this struct.
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.
Good spot!
libafl_targets/src/sancov_cmp.c
Outdated
// Note: for RETADDR to give us the fuzz target caller address we need | ||
// to guarantee that this code is inlined. `inline` keyword provides | ||
// no such guarantees, but a macro does. | ||
#if defined(SANCOV_VALUE_PROFILE) && defined(SANCOV_CMPLOG) |
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.
These macros are a bit DRY; I should pull out the repeating stuff.
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.
it's ok
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.
Have tidied them up a bit now
Ok, requested a new fuzzbench experiment with the fixes in place here. If that runs fine I'll mark this ready for review. |
Status? Got a link to the fuzzbench? :) |
Just running it again with the fixes that toka pointed out. The fuzzbench run is in progress here. |
The trial doesn't seem to run the normal version(?) |
The results get merged at the end of the run so it will have the baseline libafl (on whatever commit its currently pinned to) appear after that. Unfortunately it looks like almost all the runs have been getting pre-empted, so the outcome isn't really going to be reliable enough to draw any conclusions :/ @tokatoka has experience with fuzzbench's reliability as of late so may be able to comment more on what the best next steps are. |
we can just merge this |
I agree, I don't see how this PR could have a negative effect provided the implementation doesn't have any flaws. |
SanitizerCoverage TraceCmp has 2 sets of callbacks; the below is taken verbatim from the documentation:
Currently, libafl redirects the
__sanitizer_cov_trace_const_cmpX
functions to call__sanitizer_cov_trace_cmpX
. Knowing that an argument is constant, can however inform the replacement process as there is no value in finding a compile time constant in the input and replacing it with a runtime value. Consider the following program:If we had the input
[16, 16, 16, 8]
, and we received the callback__sanitizer_cov_trace_const_cmp1(16, 8)
, we would currently try to first match the 1st argument and then replace it with the 2nd - then try to match the 2nd argument and replace it with the 1st. Assuming we start scanning for matches at index 0, we would immediately match the16
and replace it with8
resulting in the input[8, 16, 16, 8]
. We don't get into the branch.In this patch, we pass through the
const
information so that we don't try to match on the const and replace it. For this example that means that we only look for8
, and if we find it then replace with16
- for the given input this has 100% success rate.There is currently an experiment comparing this to the baseline for fuzzbench here. I expect the results may be 1% improvement at most, but still I think it makes sense to use all of the information available to the fuzzer.