forked from OSchip/llvm-project
[libFuzzer] Instrument bcmp
If we define memcmp in an archive, bcmp should be defined as well (many libc define bcmp/memcmp in one object file). Otherwise if the application calls bcmp or strcmp which gets optimized to bcmp (SimplifyLibCalls), the undefined reference may pull in an optimized bcmp/strcmp implementation (libc replacement) later on the linker command line. If both libFuzzer's memcmp and the optimized memcmp are strong => there will be a multiple definition error.
This commit is contained in:
parent
99d03f0391
commit
f7ffb122d0
|
@ -119,6 +119,7 @@ static char *internal_strstr(const char *haystack, const char *needle) {
|
|||
|
||||
extern "C" {
|
||||
|
||||
DEFINE_REAL(int, bcmp, const void *, const void *, size_t)
|
||||
DEFINE_REAL(int, memcmp, const void *, const void *, size_t)
|
||||
DEFINE_REAL(int, strncmp, const char *, const char *, size_t)
|
||||
DEFINE_REAL(int, strcmp, const char *, const char *)
|
||||
|
@ -128,6 +129,14 @@ DEFINE_REAL(char *, strstr, const char *, const char *)
|
|||
DEFINE_REAL(char *, strcasestr, const char *, const char *)
|
||||
DEFINE_REAL(void *, memmem, const void *, size_t, const void *, size_t)
|
||||
|
||||
ATTRIBUTE_INTERFACE int bcmp(const char *s1, const char *s2, size_t n) {
|
||||
if (!FuzzerInited)
|
||||
return internal_memcmp(s1, s2, n);
|
||||
int result = REAL(bcmp)(s1, s2, n);
|
||||
__sanitizer_weak_hook_memcmp(GET_CALLER_PC(), s1, s2, n, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
ATTRIBUTE_INTERFACE int memcmp(const void *s1, const void *s2, size_t n) {
|
||||
if (!FuzzerInited)
|
||||
return internal_memcmp(s1, s2, n);
|
||||
|
@ -200,6 +209,8 @@ static void fuzzerInit() {
|
|||
return;
|
||||
FuzzerInitIsRunning = true;
|
||||
|
||||
REAL(bcmp) = reinterpret_cast<memcmp_type>(
|
||||
getFuncAddr("bcmp", reinterpret_cast<uintptr_t>(&bcmp)));
|
||||
REAL(memcmp) = reinterpret_cast<memcmp_type>(
|
||||
getFuncAddr("memcmp", reinterpret_cast<uintptr_t>(&memcmp)));
|
||||
REAL(strncmp) = reinterpret_cast<strncmp_type>(
|
||||
|
|
|
@ -8,13 +8,17 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#ifndef MEMCMP
|
||||
# define MEMCMP memcmp
|
||||
#endif
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
// TODO: check other sizes.
|
||||
if (Size >= 8 && memcmp(Data, "01234567", 8) == 0) {
|
||||
if (Size >= 12 && memcmp(Data + 8, "ABCD", 4) == 0) {
|
||||
if (Size >= 14 && memcmp(Data + 12, "XY", 2) == 0) {
|
||||
if (Size >= 17 && memcmp(Data + 14, "KLM", 3) == 0) {
|
||||
if (Size >= 27 && memcmp(Data + 17, "ABCDE-GHIJ", 10) == 0){
|
||||
if (Size >= 8 && MEMCMP(Data, "01234567", 8) == 0) {
|
||||
if (Size >= 12 && MEMCMP(Data + 8, "ABCD", 4) == 0) {
|
||||
if (Size >= 14 && MEMCMP(Data + 12, "XY", 2) == 0) {
|
||||
if (Size >= 17 && MEMCMP(Data + 14, "KLM", 3) == 0) {
|
||||
if (Size >= 27 && MEMCMP(Data + 17, "ABCDE-GHIJ", 10) == 0){
|
||||
fprintf(stderr, "BINGO %zd\n", Size);
|
||||
for (size_t i = 0; i < Size; i++) {
|
||||
uint8_t C = Data[i];
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
UNSUPPORTED: freebsd
|
||||
RUN: %cpp_compiler -DMEMCMP=bcmp %S/MemcmpTest.cpp -o %t
|
||||
RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s
|
||||
CHECK: BINGO
|
Loading…
Reference in New Issue