about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-08-11 03:40:12 +0200
committerGitHub <noreply@github.com>2020-08-11 03:40:12 +0200
commit67dac152269c48245dca88140b1238b36d5e0954 (patch)
tree81e8f262c1dc403e34c7b287ba68c81bb37cb4d0
parent9cf8637fab8cf3fe8aba5660015bbe7177805807 (diff)
parent50e76fce123f01ec83024f3bbd3190f2e1a6d387 (diff)
downloadafl++-67dac152269c48245dca88140b1238b36d5e0954.tar.gz
Merge branch 'debug' into taint
-rw-r--r--GNUmakefile3
-rw-r--r--README.md18
-rw-r--r--docs/Changelog.md3
-rw-r--r--include/afl-fuzz.h1
-rw-r--r--include/debug.h63
-rw-r--r--llvm_mode/README.lto.md20
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentation.so.cc111
-rw-r--r--llvm_mode/afl-llvm-rt.o.c23
-rw-r--r--src/afl-forkserver.c13
-rw-r--r--src/afl-fuzz-cmplog.c4
-rw-r--r--src/afl-fuzz-mutators.c1
-rw-r--r--src/afl-fuzz-one.c2
-rw-r--r--src/afl-fuzz-run.c2
-rw-r--r--src/afl-fuzz.c5
-rwxr-xr-xtest/test-basic.sh2
15 files changed, 187 insertions, 84 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 4d0c434e..027ebfd9 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -98,7 +98,7 @@ ifneq "$(shell uname -m)" "x86_64"
 endif
 
 CFLAGS     ?= -O3 -funroll-loops $(CFLAGS_OPT)
-override CFLAGS += -g -Wno-pointer-sign \
+override CFLAGS += -g -Wno-pointer-sign -Wno-variadic-macros -Wall -Wextra -Wpointer-arith \
 			  -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
 			  -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
 
@@ -198,6 +198,7 @@ else
 endif
 
 ifneq "$(filter Linux GNU%,$(shell uname))" ""
+  override CFLAGS += -D_FORTIFY_SOURCE=2
   LDFLAGS += -ldl -lrt
 endif
 
diff --git a/README.md b/README.md
index d2dc4a95..2b9bc588 100644
--- a/README.md
+++ b/README.md
@@ -71,18 +71,18 @@ only new bytes in the other cycle.
   Android support and much, much, much more.
 
   | Feature/Instrumentation  | afl-gcc | llvm_mode | gcc_plugin | qemu_mode        | unicorn_mode |
-  | ------------------------ |:-------:|:---------:|:----------:|:----------------:|:------------:|
-  | NeverZero                |    x    |     x(1)  |      (2)   |         x        |       x      |
-  | Persistent mode          |         |     x     |     x      | x86[_64]/arm[64] |       x      |
+  | -------------------------|:-------:|:---------:|:----------:|:----------------:|:------------:|
+  | NeverZero                | x86[_64]|     x(1)  |      (2)   |         x        |       x      |
+  | Persistent Mode          |         |     x     |     x      | x86[_64]/arm[64] |       x      |
   | LAF-Intel / CompCov      |         |     x     |            | x86[_64]/arm[64] | x86[_64]/arm |
   | CmpLog                   |         |     x     |            | x86[_64]/arm[64] |              |
-  | Selective instrumentation|         |     x     |     x      |        (x)(3)    |              |
-  | Non-colliding coverage   |         |     x(4)  |            |        (x)(5)    |              |
+  | Selective Instrumentation|         |     x     |     x      |        (x)(3)    |              |
+  | Non-Colliding Coverage   |         |     x(4)  |            |        (x)(5)    |              |
   | InsTrim                  |         |     x     |            |                  |              |
-  | Ngram prev_loc coverage  |         |     x(6)  |            |                  |              |
-  | Context coverage         |         |     x     |            |                  |              |
-  | Auto dictionary          |         |     x(7)  |            |                  |              |
-  | Snapshot LKM support     |         |     x     |            |        (x)(5)    |              |
+  | Ngram prev_loc Coverage  |         |     x(6)  |            |                  |              |
+  | Context Coverage         |         |     x     |            |                  |              |
+  | Auto Dictionary          |         |     x(7)  |            |                  |              |
+  | Snapshot LKM Support     |         |     x     |            |        (x)(5)    |              |
 
   1. default for LLVM >= 9.0, env var for older version due an efficiency bug in llvm <= 8
   2. GCC creates non-performant code, hence it is disabled in gcc_plugin
diff --git a/docs/Changelog.md b/docs/Changelog.md
index f8742b1c..25c7a761 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -28,6 +28,9 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
        sancov, and also supports function matching!
      - fixes for laf-intel float splitting (thanks to mark-griffin for
        reporting)
+     - LTO: switch default to the dynamic memory map, set AFL_LLVM_MAP_ADDR
+            for a fixed map address (eg. 0x10000)
+     - LTO: skipping ctors and ifuncs in fix map address instrumentation
      - LTO: autodictionary mode is a default
      - LTO: instrim instrumentation disabled, only classic support used
             as it is always better
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 88392867..02c36861 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -670,6 +670,7 @@ typedef struct afl_state {
 struct custom_mutator {
 
   const char *name;
+  char *      name_short;
   void *      dh;
   u8 *        post_process_buf;
   size_t      post_process_size;
diff --git a/include/debug.h b/include/debug.h
index ae2946f0..f9ebce58 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -28,11 +28,6 @@
 #include "types.h"
 #include "config.h"
 
-/* __FUNCTION__ is non-iso */
-#ifdef __func__
-  #define __FUNCTION__ __func__
-#endif
-
 /*******************
  * Terminal colors *
  *******************/
@@ -223,43 +218,43 @@
 
 /* Die with a verbose non-OS fatal error message. */
 
-#define FATAL(x...)                                                          \
-  do {                                                                       \
-                                                                             \
-    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                                \
-         "\n[-] PROGRAM ABORT : " cRST   x);                                   \
-    SAYF(cLRD "\n         Location : " cRST "%s(), %s:%u\n\n", __FUNCTION__, \
-         __FILE__, __LINE__);                                                \
-    exit(1);                                                                 \
-                                                                             \
+#define FATAL(x...)                                                      \
+  do {                                                                   \
+                                                                         \
+    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                            \
+         "\n[-] PROGRAM ABORT : " cRST   x);                               \
+    SAYF(cLRD "\n         Location : " cRST "%s(), %s:%u\n\n", __func__, \
+         __FILE__, __LINE__);                                            \
+    exit(1);                                                             \
+                                                                         \
   } while (0)
 
 /* Die by calling abort() to provide a core dump. */
 
-#define ABORT(x...)                                                          \
-  do {                                                                       \
-                                                                             \
-    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                                \
-         "\n[-] PROGRAM ABORT : " cRST   x);                                   \
-    SAYF(cLRD "\n    Stop location : " cRST "%s(), %s:%u\n\n", __FUNCTION__, \
-         __FILE__, __LINE__);                                                \
-    abort();                                                                 \
-                                                                             \
+#define ABORT(x...)                                                      \
+  do {                                                                   \
+                                                                         \
+    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                            \
+         "\n[-] PROGRAM ABORT : " cRST   x);                               \
+    SAYF(cLRD "\n    Stop location : " cRST "%s(), %s:%u\n\n", __func__, \
+         __FILE__, __LINE__);                                            \
+    abort();                                                             \
+                                                                         \
   } while (0)
 
 /* Die while also including the output of perror(). */
 
-#define PFATAL(x...)                                                       \
-  do {                                                                     \
-                                                                           \
-    fflush(stdout);                                                        \
-    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                              \
-         "\n[-]  SYSTEM ERROR : " cRST   x);                                 \
-    SAYF(cLRD "\n    Stop location : " cRST "%s(), %s:%u\n", __FUNCTION__, \
-         __FILE__, __LINE__);                                              \
-    SAYF(cLRD "       OS message : " cRST "%s\n", strerror(errno));        \
-    exit(1);                                                               \
-                                                                           \
+#define PFATAL(x...)                                                   \
+  do {                                                                 \
+                                                                       \
+    fflush(stdout);                                                    \
+    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                          \
+         "\n[-]  SYSTEM ERROR : " cRST   x);                             \
+    SAYF(cLRD "\n    Stop location : " cRST "%s(), %s:%u\n", __func__, \
+         __FILE__, __LINE__);                                          \
+    SAYF(cLRD "       OS message : " cRST "%s\n", strerror(errno));    \
+    exit(1);                                                           \
+                                                                       \
   } while (0)
 
 /* Die with FATAL() or PFATAL() depending on the value of res (used to
diff --git a/llvm_mode/README.lto.md b/llvm_mode/README.lto.md
index 4d643324..9046c5a8 100644
--- a/llvm_mode/README.lto.md
+++ b/llvm_mode/README.lto.md
@@ -17,9 +17,6 @@ This version requires a current llvm 11+ compiled from the github master.
 5. If any problems arise be sure to set `AR=llvm-ar RANLIB=llvm-ranlib`.
    Some targets might need `LD=afl-clang-lto` and others `LD=afl-ld-lto`.
 
-6. If a target uses _init functions or early constructors then additionally
-   set `AFL_LLVM_MAP_DYNAMIC=1` as your target will crash otherwise!
-
 ## Introduction and problem description
 
 A big issue with how afl/afl++ works is that the basic block IDs that are
@@ -128,14 +125,14 @@ on start. This improves coverage statistically by 5-10% :)
 
 ## Fixed memory map
 
-To speed up fuzzing, the shared memory map is hard set to a specific address,
-by default 0x10000. In most cases this will work without any problems.
+To speed up fuzzing, it is possible to set a fixed shared memory map.
+Recommened is the value 0x10000.
+In most cases this will work without any problems. However if a target uses
+early constructors, ifuncs or a deferred forkserver this can crash the target.
 On unusual operating systems/processors/kernels or weird libraries this might
 fail so to change the fixed address at compile time set
 AFL_LLVM_MAP_ADDR with a better value (a value of 0 or empty sets the map address
 to be dynamic - the original afl way, which is slower).
-AFL_LLVM_MAP_DYNAMIC can be set so the shared memory address is dynamic (which
-is safer but also slower).
 
 ## Document edge IDs
 
@@ -262,15 +259,6 @@ If this succeeeds then there is an issue with afl-clang-lto. Please report at
 Even some targets where clang-12 fails can be build if the fail is just in
 `./configure`, see `Solving difficult targets` above.
 
-### Target crashes immediately
-
-If the target is using early constructors (priority values smaller than 6)
-or have their own _init/.init functions and these are instrumented then the
-target will likely crash when started. This can be avoided by compiling with
-`AFL_LLVM_MAP_DYNAMIC=1` .
-
-This can e.g. happen with OpenSSL.
-
 ## History
 
 This was originally envisioned by hexcoder- in Summer 2019, however we saw no
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
index 38c3f202..fd8e48a7 100644
--- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
@@ -49,6 +49,7 @@
 #include "llvm/Analysis/MemorySSAUpdater.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/Pass.h"
+#include "llvm/IR/Constants.h"
 
 #include "afl-llvm-common.h"
 
@@ -135,7 +136,10 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   if (getenv("AFL_LLVM_LTO_AUTODICTIONARY")) autodictionary = 1;
 
-  if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0;
+  // we make this the default as the fixed map has problems with
+  // defered forkserver, early constructors, ifuncs and maybe more
+  /*if (getenv("AFL_LLVM_MAP_DYNAMIC"))*/
+  map_addr = 0;
 
   if (getenv("AFL_LLVM_SKIPSINGLEBLOCK")) function_minimum_size = 2;
 
@@ -196,7 +200,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
   ConstantInt *Zero = ConstantInt::get(Int8Ty, 0);
   ConstantInt *One = ConstantInt::get(Int8Ty, 1);
 
-  /* This dumps all inialized global strings - might be useful in the future
+  // This dumps all inialized global strings - might be useful in the future
+  /*
   for (auto G=M.getGlobalList().begin(); G!=M.getGlobalList().end(); G++) {
 
     GlobalVariable &GV=*G;
@@ -212,7 +217,79 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   }
 
-  */
+    */
+
+  std::vector<std::string> module_block_list;
+
+  if (map_addr) {
+
+    for (GlobalIFunc &IF : M.ifuncs()) {
+
+      StringRef ifunc_name = IF.getName();
+      Constant *r = IF.getResolver();
+      StringRef r_name = cast<Function>(r->getOperand(0))->getName();
+      if (!be_quiet)
+        fprintf(stderr,
+                "Warning: Found an ifunc with name %s that points to resolver "
+                "function %s, we cannot instrument this, putting it into a "
+                "block list.\n",
+                ifunc_name.str().c_str(), r_name.str().c_str());
+      module_block_list.push_back(r_name.str());
+
+    }
+
+    GlobalVariable *GV = M.getNamedGlobal("llvm.global_ctors");
+    if (GV && !GV->isDeclaration() && !GV->hasLocalLinkage()) {
+
+      ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
+
+      if (InitList) {
+
+        for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
+
+          if (ConstantStruct *CS =
+                  dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
+
+            if (CS->getNumOperands() >= 2) {
+
+              if (CS->getOperand(1)->isNullValue())
+                break;  // Found a null terminator, stop here.
+
+              ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
+              int          Priority = CI ? CI->getSExtValue() : 0;
+
+              Constant *FP = CS->getOperand(1);
+              if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
+                if (CE->isCast()) FP = CE->getOperand(0);
+              if (Function *F = dyn_cast<Function>(FP)) {
+
+                if (!F->isDeclaration() &&
+                    strncmp(F->getName().str().c_str(), "__afl", 5) != 0 &&
+                    Priority <= 5) {
+
+                  if (!be_quiet)
+                    fprintf(stderr,
+                            "Warning: Found constructor function %s with prio "
+                            "%u, we cannot instrument this, putting it into a "
+                            "block list.\n",
+                            F->getName().str().c_str(), Priority);
+                  module_block_list.push_back(F->getName().str());
+
+                }
+
+              }
+
+            }
+
+          }
+
+        }
+
+      }
+
+    }
+
+  }
 
   /* Instrument all the things! */
 
@@ -220,12 +297,36 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   for (auto &F : M) {
 
-    // fprintf(stderr, "DEBUG: Module %s Function %s\n",
-    // M.getName().str().c_str(), F.getName().str().c_str());
+    /*For debugging
+    AttributeSet X = F.getAttributes().getFnAttributes();
+    fprintf(stderr, "DEBUG: Module %s Function %s attributes %u\n",
+      M.getName().str().c_str(), F.getName().str().c_str(),
+      X.getNumAttributes());
+    */
 
     if (F.size() < function_minimum_size) continue;
     if (isIgnoreFunction(&F)) continue;
 
+    if (module_block_list.size()) {
+
+      for (auto bname : module_block_list) {
+
+        std::string fname = F.getName().str();
+
+        if (fname.compare(bname) == 0) {
+
+          if (!be_quiet)
+            WARNF(
+                "Skipping instrumentation of dangerous early running function "
+                "%s",
+                fname.c_str());
+
+        }
+
+      }
+
+    }
+
     // the instrument file list check
     AttributeList Attrs = F.getAttributes();
     if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) {
diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c
index 32903d2f..c69d8bb7 100644
--- a/llvm_mode/afl-llvm-rt.o.c
+++ b/llvm_mode/afl-llvm-rt.o.c
@@ -329,10 +329,13 @@ static void __afl_map_shm(void) {
 
   id_str = getenv(CMPLOG_SHM_ENV_VAR);
 
-  if (getenv("AFL_DEBUG"))
+  if (getenv("AFL_DEBUG")) {
+
     fprintf(stderr, "DEBUG: cmplog id_str %s\n",
             id_str == NULL ? "<null>" : id_str);
 
+  }
+
   if (id_str) {
 
 #ifdef USEMMAP
@@ -404,9 +407,12 @@ static void __afl_start_snapshots(void) {
 
     if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
 
-    if (getenv("AFL_DEBUG"))
+    if (getenv("AFL_DEBUG")) {
+
       fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
 
+    }
+
     if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) ==
         (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) {
 
@@ -613,9 +619,12 @@ static void __afl_start_forkserver(void) {
 
     if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
 
-    if (getenv("AFL_DEBUG"))
+    if (getenv("AFL_DEBUG")) {
+
       fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
 
+    }
+
     if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) ==
         (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) {
 
@@ -936,8 +945,12 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
   u32   inst_ratio = 100;
   char *x;
 
-  fprintf(stderr, "Running __sanitizer_cov_trace_pc_guard_init: %p-%p\n", start,
-          stop);
+  if (getenv("AFL_DEBUG")) {
+
+    fprintf(stderr, "Running __sanitizer_cov_trace_pc_guard_init: %p-%p\n",
+            start, stop);
+
+  }
 
   if (start == stop || *start) return;
 
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 4dc5e438..adb75a2d 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -293,8 +293,8 @@ static void report_error_and_exit(int error) {
       FATAL(
           "the fuzzing target reports that hardcoded map address might be the "
           "reason the mmap of the shared memory failed. Solution: recompile "
-          "the target with either afl-clang-lto and the environment variable "
-          "AFL_LLVM_MAP_DYNAMIC set or recompile with afl-clang-fast.");
+          "the target with either afl-clang-lto and do not set "
+          "AFL_LLVM_MAP_ADDR or recompile with afl-clang-fast.");
       break;
     case FS_ERROR_SHM_OPEN:
       FATAL("the fuzzing target reports that the shm_open() call failed.");
@@ -838,8 +838,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
     SAYF("\n" cLRD "[-] " cRST
          "Hmm, looks like the target binary terminated before we could"
          " complete a handshake with the injected code.\n"
-         "If the target was compiled with afl-clang-lto then recompiling with"
-         " AFL_LLVM_MAP_DYNAMIC might solve your problem.\n"
+         "If the target was compiled with afl-clang-lto and AFL_LLVM_MAP_ADDR"
+         " then recompiling without this parameter.\n"
          "Otherwise there is a horrible bug in the fuzzer.\n"
          "Poke <afl-users@googlegroups.com> for troubleshooting tips.\n");
 
@@ -870,9 +870,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
         "    - the target was compiled with afl-clang-lto and a constructor "
         "was\n"
-        "      instrumented, recompiling with AFL_LLVM_MAP_DYNAMIC might solve "
-        "your\n"
-        "      problem\n\n"
+        "      instrumented, recompiling without AFL_LLVM_MAP_ADDR might solve "
+        "your problem\n\n"
 
         "    - Less likely, there is a horrible bug in the fuzzer. If other "
         "options\n"
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index faf4dcb7..8ffc6e1b 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -29,10 +29,6 @@
 #include "afl-fuzz.h"
 #include "cmplog.h"
 
-typedef struct cmplog_data {
-
-} cmplog_data_t;
-
 void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv) {
 
   setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1);
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index b30106a0..0fa646f9 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -142,6 +142,7 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
   struct custom_mutator *mutator = ck_alloc(sizeof(struct custom_mutator));
 
   mutator->name = fn;
+  mutator->name_short = strrchr(fn, '/') + 1;
   ACTF("Loading custom mutator library from '%s'...", fn);
 
   dh = dlopen(fn, RTLD_NOW);
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 75687703..9f38b8f8 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -1764,6 +1764,8 @@ custom_mutator_stage:
 
       has_custom_fuzz = true;
 
+      afl->stage_short = el->name_short;
+
       for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max;
            ++afl->stage_cur) {
 
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 0aef1c9e..9db23134 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -138,7 +138,7 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
 
 /* The same, but with an adjustable gap. Used for trimming. */
 
-static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at,
+static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at,
                            u32 skip_len) {
 
   s32 fd = afl->fsrv.out_fd;
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index fc9cbb6c..11db004d 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -300,9 +300,12 @@ int main(int argc, char **argv_orig, char **envp) {
 
         if (afl->cpu_to_bind != -1) FATAL("Multiple -b options not supported");
 
-        if (sscanf(optarg, "%u", &afl->cpu_to_bind) < 0 || optarg[0] == '-')
+        if (sscanf(optarg, "%d", &afl->cpu_to_bind) < 0) {
+
           FATAL("Bad syntax used for -b");
 
+        }
+
         break;
 
       }
diff --git a/test/test-basic.sh b/test/test-basic.sh
index 5ce5630b..9e4b03c3 100755
--- a/test/test-basic.sh
+++ b/test/test-basic.sh
@@ -120,7 +120,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
  }
 } || {
  $ECHO "$YELLOW[-] not an intel platform, cannot test afl-gcc"
- INCOMPLETE=1
+ #this is not incomplete as this feature doesnt exist, so all good
 }
 
 . ./test-post.sh