forked from OSchip/llvm-project
[libFuzzer] extend the weak memcmp/strcmp/strncmp interceptors to receive the result of the computations. With that, don't do any mutations if memcmp/etc returned 0
llvm-svn: 257423
This commit is contained in:
parent
7087a51b13
commit
e3580956ea
|
@ -125,9 +125,11 @@ extern "C" {
|
|||
// to know what is being passed to libc functions, e.g. memcmp.
|
||||
// FIXME: implement more hooks.
|
||||
void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
|
||||
const void *s2, size_t n);
|
||||
const void *s2, size_t n, int result);
|
||||
void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
|
||||
const char *s2, size_t n);
|
||||
const char *s2, size_t n, int result);
|
||||
void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
|
||||
const char *s2, int result);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
@ -214,13 +214,11 @@ static inline int CharCmpX(unsigned char c1, unsigned char c2) {
|
|||
}
|
||||
|
||||
DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
|
||||
const char *s1, const char *s2)
|
||||
const char *s1, const char *s2, int result)
|
||||
|
||||
INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
|
||||
CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
|
||||
s2);
|
||||
unsigned char c1, c2;
|
||||
uptr i;
|
||||
for (i = 0;; i++) {
|
||||
|
@ -230,19 +228,21 @@ INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
|
|||
}
|
||||
COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
|
||||
COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
|
||||
return CharCmpX(c1, c2);
|
||||
int result = CharCmpX(c1, c2);
|
||||
CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
|
||||
s2, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,
|
||||
const char *s1, const char *s2, uptr n)
|
||||
const char *s1, const char *s2, uptr n,
|
||||
int result)
|
||||
|
||||
INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
|
||||
if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
|
||||
return internal_strncmp(s1, s2, size);
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
|
||||
CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
|
||||
s2, size);
|
||||
unsigned char c1 = 0, c2 = 0;
|
||||
uptr i;
|
||||
for (i = 0; i < size; i++) {
|
||||
|
@ -252,7 +252,10 @@ INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
|
|||
}
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
|
||||
return CharCmpX(c1, c2);
|
||||
int result = CharCmpX(c1, c2);
|
||||
CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
|
||||
s2, size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
|
||||
|
@ -400,15 +403,14 @@ INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
|
|||
#if SANITIZER_INTERCEPT_MEMCMP
|
||||
|
||||
DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
|
||||
const void *s1, const void *s2, uptr n)
|
||||
const void *s1, const void *s2, uptr n,
|
||||
int result)
|
||||
|
||||
INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
|
||||
if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
|
||||
return internal_memcmp(a1, a2, size);
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
|
||||
CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
|
||||
a2, size);
|
||||
if (common_flags()->intercept_memcmp) {
|
||||
if (common_flags()->strict_memcmp) {
|
||||
// Check the entire regions even if the first bytes of the buffers are
|
||||
|
@ -428,10 +430,16 @@ INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
|
|||
}
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
|
||||
return CharCmpX(c1, c2);
|
||||
int r = CharCmpX(c1, c2);
|
||||
CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(),
|
||||
a1, a2, size, r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return REAL(memcmp(a1, a2, size));
|
||||
int result = REAL(memcmp(a1, a2, size));
|
||||
CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
|
||||
a2, size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
|
||||
|
|
|
@ -539,16 +539,18 @@ void dfsan_weak_hook_strcmp(void *caller_pc, const char *s1, const char *s2,
|
|||
}
|
||||
|
||||
void __sanitizer_weak_hook_memcmp(void *caller_pc, const void *s1,
|
||||
const void *s2, size_t n) {
|
||||
const void *s2, size_t n, int result) {
|
||||
if (!TS) return;
|
||||
if (result == 0) return; // No reason to mutate.
|
||||
if (n <= 1) return; // Not interesting.
|
||||
TS->TraceMemcmpCallback(n, reinterpret_cast<const uint8_t *>(s1),
|
||||
reinterpret_cast<const uint8_t *>(s2));
|
||||
}
|
||||
|
||||
void __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,
|
||||
const char *s2, size_t n) {
|
||||
const char *s2, size_t n, int result) {
|
||||
if (!TS) return;
|
||||
if (result == 0) return; // No reason to mutate.
|
||||
size_t Len1 = fuzzer::InternalStrnlen(s1, n);
|
||||
size_t Len2 = fuzzer::InternalStrnlen(s2, n);
|
||||
n = std::min(n, Len1);
|
||||
|
@ -559,8 +561,9 @@ void __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,
|
|||
}
|
||||
|
||||
void __sanitizer_weak_hook_strcmp(void *caller_pc, const char *s1,
|
||||
const char *s2) {
|
||||
const char *s2, int result) {
|
||||
if (!TS) return;
|
||||
if (result == 0) return; // No reason to mutate.
|
||||
size_t Len1 = strlen(s1);
|
||||
size_t Len2 = strlen(s2);
|
||||
size_t N = std::min(Len1, Len2);
|
||||
|
|
Loading…
Reference in New Issue