about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvanhauser-thc <vh@thc.org>2021-02-15 13:25:15 +0100
committervanhauser-thc <vh@thc.org>2021-02-15 13:25:15 +0100
commite3a5c31307f323452dc4b5288e0d19a02b596a33 (patch)
treecca651d72e43fd7eca29c28a3d47326c98cdb433
parentdd2fd8027454acaa5c12beea6f7b721fc8794715 (diff)
downloadafl++-e3a5c31307f323452dc4b5288e0d19a02b596a33.tar.gz
llvm bug workaround for lto extint
-rw-r--r--docs/Changelog.md1
-rw-r--r--include/envs.h1
-rw-r--r--instrumentation/cmplog-instructions-pass.cc39
-rw-r--r--qemu_mode/libqasan/dlmalloc.c5
-rw-r--r--src/afl-cc.c2
-rw-r--r--src/afl-fuzz-redqueen.c1
6 files changed, 45 insertions, 4 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 71ef4c2c..e2482f8f 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -49,6 +49,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
       CLANG for old afl-clang
     - fixed a potential crash in the LAF feature
     - workaround for llvm 13
+    - workaround for llvm internal lto bug that lets not bitcast from _ExtInt()
   - qemuafl
     - QASan (address sanitizer for Qemu) ported to qemuafl!
       See qemu_mode/libqasan/README.md
diff --git a/include/envs.h b/include/envs.h
index 4313e053..36667ebc 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -16,6 +16,7 @@ static char *afl_environment_deprecated[] = {
 
 static char *afl_environment_variables[] = {
 
+    "_AFL_LTO_COMPILE",
     "AFL_ALIGNED_ALLOC",
     "AFL_ALLOW_TMP",
     "AFL_ANALYZE_HEX",
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index b5cc1882..6b071b48 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -113,6 +113,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
   IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
   IntegerType *Int128Ty = IntegerType::getInt128Ty(C);
 
+  char *is_lto = getenv("_AFL_LTO_COMPILE");
+
 #if LLVM_VERSION_MAJOR < 9
   Constant *
 #else
@@ -265,10 +267,20 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
       unsigned int  max_size = Val->getType()->getIntegerBitWidth(), cast_size;
       unsigned char do_cast = 0;
 
-      if (!SI->getNumCases() || max_size < 16 || max_size % 8) {
+      if (!SI->getNumCases() || max_size < 16) { continue; }
+
+      if (max_size % 8) {
+
+        if (is_lto) {
+
+          continue;  // LTO cannot bitcast from _ExtInt() :(
+
+        } else {
 
-        // if (!be_quiet) errs() << "skip trivial switch..\n";
-        continue;
+          max_size = (((max_size / 8) + 1) * 8);
+          do_cast = 1;
+
+        }
 
       }
 
@@ -285,6 +297,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
 
         }
 
+        if (is_lto) { continue; }  // LTO cannot bitcast _ExtInt() :(
         max_size = 128;
         do_cast = 1;
 
@@ -301,6 +314,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
           cast_size = max_size;
           break;
         default:
+          if (is_lto) { continue; }  // LTO cannot bitcast _ExtInt() :(
           cast_size = 128;
           do_cast = 1;
 
@@ -540,7 +554,22 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
 
       }
 
-      if (!max_size || max_size % 8 || max_size < 16) { continue; }
+      if (!max_size || max_size < 16) { continue; }
+
+      if (max_size % 8) {
+
+        if (is_lto) {
+
+          continue;  // LTO cannot bitcast from _ExtInt() :(
+
+        } else {
+
+          max_size = (((max_size / 8) + 1) * 8);
+          do_cast = 1;
+
+        }
+
+      }
 
       if (max_size > 128) {
 
@@ -552,6 +581,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
 
         }
 
+        if (is_lto) { continue; }  // LTO cannot bitcast from _ExtInt() :(
         max_size = 128;
         do_cast = 1;
 
@@ -568,6 +598,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
           cast_size = max_size;
           break;
         default:
+          if (is_lto) { continue; }  // LTO cannot bitcast from _ExtInt() :(
           cast_size = 128;
           do_cast = 1;
 
diff --git a/qemu_mode/libqasan/dlmalloc.c b/qemu_mode/libqasan/dlmalloc.c
index bace0ff6..aff58ad5 100644
--- a/qemu_mode/libqasan/dlmalloc.c
+++ b/qemu_mode/libqasan/dlmalloc.c
@@ -3917,6 +3917,7 @@ static void internal_malloc_stats(mstate m) {
                                                                 \
         } else if (RTCHECK(B == smallbin_at(M, I) ||            \
                                                                 \
+                                                                \
                            (ok_address(M, B) && B->fd == P))) { \
                                                                 \
           F->bk = B;                                            \
@@ -4128,6 +4129,7 @@ static void internal_malloc_stats(mstate m) {
                                                                      \
         } else                                                       \
                                                                      \
+                                                                     \
           CORRUPTION_ERROR_ACTION(M);                                \
         if (R != 0) {                                                \
                                                                      \
@@ -4144,6 +4146,7 @@ static void internal_malloc_stats(mstate m) {
                                                                      \
               } else                                                 \
                                                                      \
+                                                                     \
                 CORRUPTION_ERROR_ACTION(M);                          \
                                                                      \
             }                                                        \
@@ -4156,12 +4159,14 @@ static void internal_malloc_stats(mstate m) {
                                                                      \
               } else                                                 \
                                                                      \
+                                                                     \
                 CORRUPTION_ERROR_ACTION(M);                          \
                                                                      \
             }                                                        \
                                                                      \
           } else                                                     \
                                                                      \
+                                                                     \
             CORRUPTION_ERROR_ACTION(M);                              \
                                                                      \
         }                                                            \
diff --git a/src/afl-cc.c b/src/afl-cc.c
index d41f79a2..959c9a6f 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -1875,6 +1875,8 @@ int main(int argc, char **argv, char **envp) {
 
   edit_params(argc, argv, envp);
 
+  if (lto_mode) { setenv("_AFL_LTO_COMPILE", "1", 1); }
+
   if (debug) {
 
     DEBUGF("cd '%s';", getthecwd());
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 527feef5..2b01ecad 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -1533,6 +1533,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
       is_n = 1;
 
   }
+
 #endif
 
   for (i = 0; i < loggeds; ++i) {