github.com/prysmaticlabs/prysm@v1.4.4/third_party/afl/llvm_mode/afl-llvm-rt.o.c (about)

     1  /*
     2     american fuzzy lop - LLVM instrumentation bootstrap
     3     ---------------------------------------------------
     4  
     5     Written by Laszlo Szekeres <lszekeres@google.com> and
     6                Michal Zalewski <lcamtuf@google.com>
     7  
     8     LLVM integration design comes from Laszlo Szekeres.
     9  
    10     Copyright 2015, 2016 Google Inc. All rights reserved.
    11  
    12     Licensed under the Apache License, Version 2.0 (the "License");
    13     you may not use this file except in compliance with the License.
    14     You may obtain a copy of the License at:
    15  
    16       http://www.apache.org/licenses/LICENSE-2.0
    17  
    18     This code is the rewrite of afl-as.h's main_payload.
    19  
    20  */
    21  
    22  #include "../config.h"
    23  #include "../types.h"
    24  
    25  #include <stdio.h>
    26  #include <stdlib.h>
    27  #include <signal.h>
    28  #include <unistd.h>
    29  #include <string.h>
    30  #include <assert.h>
    31  
    32  #include <sys/mman.h>
    33  #include <sys/shm.h>
    34  #include <sys/wait.h>
    35  #include <sys/types.h>
    36  
    37  /* This is a somewhat ugly hack for the experimental 'trace-pc-guard' mode.
    38     Basically, we need to make sure that the forkserver is initialized after
    39     the LLVM-generated runtime initialization pass, not before. */
    40  
    41  #ifdef USE_TRACE_PC
    42  #  define CONST_PRIO 5
    43  #else
    44  #  define CONST_PRIO 0
    45  #endif /* ^USE_TRACE_PC */
    46  
    47  
    48  /* Globals needed by the injected instrumentation. The __afl_area_initial region
    49     is used for instrumentation output before __afl_map_shm() has a chance to run.
    50     It will end up as .comm, so it shouldn't be too wasteful. */
    51  
    52  u8  __afl_area_initial[MAP_SIZE];
    53  u8* __afl_area_ptr = __afl_area_initial;
    54  
    55  __thread u32 __afl_prev_loc;
    56  
    57  
    58  /* Running in persistent mode? */
    59  
    60  static u8 is_persistent;
    61  
    62  
    63  /* SHM setup. */
    64  
    65  static void __afl_map_shm(void) {
    66  
    67    u8 *id_str = getenv(SHM_ENV_VAR);
    68  
    69    /* If we're running under AFL, attach to the appropriate region, replacing the
    70       early-stage __afl_area_initial region that is needed to allow some really
    71       hacky .init code to work correctly in projects such as OpenSSL. */
    72  
    73    if (id_str) {
    74  
    75      u32 shm_id = atoi(id_str);
    76  
    77      __afl_area_ptr = shmat(shm_id, NULL, 0);
    78  
    79      /* Whooooops. */
    80  
    81      if (__afl_area_ptr == (void *)-1) _exit(1);
    82  
    83      /* Write something into the bitmap so that even with low AFL_INST_RATIO,
    84         our parent doesn't give up on us. */
    85  
    86      __afl_area_ptr[0] = 1;
    87  
    88    }
    89  
    90  }
    91  
    92  
    93  /* Fork server logic. */
    94  
    95  static void __afl_start_forkserver(void) {
    96  
    97    static u8 tmp[4];
    98    s32 child_pid;
    99  
   100    u8  child_stopped = 0;
   101  
   102    /* Phone home and tell the parent that we're OK. If parent isn't there,
   103       assume we're not running in forkserver mode and just execute program. */
   104  
   105    if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
   106  
   107    while (1) {
   108  
   109      u32 was_killed;
   110      int status;
   111  
   112      /* Wait for parent by reading from the pipe. Abort if read fails. */
   113  
   114      if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
   115  
   116      /* If we stopped the child in persistent mode, but there was a race
   117         condition and afl-fuzz already issued SIGKILL, write off the old
   118         process. */
   119  
   120      if (child_stopped && was_killed) {
   121        child_stopped = 0;
   122        if (waitpid(child_pid, &status, 0) < 0) _exit(1);
   123      }
   124  
   125      if (!child_stopped) {
   126  
   127        /* Once woken up, create a clone of our process. */
   128  
   129        child_pid = fork();
   130        if (child_pid < 0) _exit(1);
   131  
   132        /* In child process: close fds, resume execution. */
   133  
   134        if (!child_pid) {
   135  
   136          close(FORKSRV_FD);
   137          close(FORKSRV_FD + 1);
   138          return;
   139    
   140        }
   141  
   142      } else {
   143  
   144        /* Special handling for persistent mode: if the child is alive but
   145           currently stopped, simply restart it with SIGCONT. */
   146  
   147        kill(child_pid, SIGCONT);
   148        child_stopped = 0;
   149  
   150      }
   151  
   152      /* In parent process: write PID to pipe, then wait for child. */
   153  
   154      if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) _exit(1);
   155  
   156      if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0)
   157        _exit(1);
   158  
   159      /* In persistent mode, the child stops itself with SIGSTOP to indicate
   160         a successful run. In this case, we want to wake it up without forking
   161         again. */
   162  
   163      if (WIFSTOPPED(status)) child_stopped = 1;
   164  
   165      /* Relay wait status to pipe, then loop back. */
   166  
   167      if (write(FORKSRV_FD + 1, &status, 4) != 4) _exit(1);
   168  
   169    }
   170  
   171  }
   172  
   173  
   174  /* A simplified persistent mode handler, used as explained in README.llvm. */
   175  
   176  int __afl_persistent_loop(unsigned int max_cnt) {
   177  
   178    static u8  first_pass = 1;
   179    static u32 cycle_cnt;
   180  
   181    if (first_pass) {
   182  
   183      /* Make sure that every iteration of __AFL_LOOP() starts with a clean slate.
   184         On subsequent calls, the parent will take care of that, but on the first
   185         iteration, it's our job to erase any trace of whatever happened
   186         before the loop. */
   187  
   188      if (is_persistent) {
   189  
   190        memset(__afl_area_ptr, 0, MAP_SIZE);
   191        __afl_area_ptr[0] = 1;
   192        __afl_prev_loc = 0;
   193      }
   194  
   195      cycle_cnt  = max_cnt;
   196      first_pass = 0;
   197      return 1;
   198  
   199    }
   200  
   201    if (is_persistent) {
   202  
   203      if (--cycle_cnt) {
   204  
   205        raise(SIGSTOP);
   206  
   207        __afl_area_ptr[0] = 1;
   208        __afl_prev_loc = 0;
   209  
   210        return 1;
   211  
   212      } else {
   213  
   214        /* When exiting __AFL_LOOP(), make sure that the subsequent code that
   215           follows the loop is not traced. We do that by pivoting back to the
   216           dummy output region. */
   217  
   218        __afl_area_ptr = __afl_area_initial;
   219  
   220      }
   221  
   222    }
   223  
   224    return 0;
   225  
   226  }
   227  
   228  
   229  /* This one can be called from user code when deferred forkserver mode
   230      is enabled. */
   231  
   232  void __afl_manual_init(void) {
   233  
   234    static u8 init_done;
   235  
   236    if (!init_done) {
   237  
   238      __afl_map_shm();
   239      __afl_start_forkserver();
   240      init_done = 1;
   241  
   242    }
   243  
   244  }
   245  
   246  
   247  /* Proper initialization routine. */
   248  
   249  __attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) {
   250  
   251    is_persistent = !!getenv(PERSIST_ENV_VAR);
   252  
   253    if (getenv(DEFER_ENV_VAR)) return;
   254  
   255    __afl_manual_init();
   256  
   257  }
   258  
   259  
   260  /* The following stuff deals with supporting -fsanitize-coverage=trace-pc-guard.
   261     It remains non-operational in the traditional, plugin-backed LLVM mode.
   262     For more info about 'trace-pc-guard', see README.llvm.
   263  
   264     The first function (__sanitizer_cov_trace_pc_guard) is called back on every
   265     edge (as opposed to every basic block). */
   266  
   267  void __sanitizer_cov_trace_pc_guard(uint32_t* guard) {
   268    __afl_area_ptr[*guard]++;
   269  }
   270  
   271  
   272  /* Init callback. Populates instrumentation IDs. Note that we're using
   273     ID of 0 as a special value to indicate non-instrumented bits. That may
   274     still touch the bitmap, but in a fairly harmless way. */
   275  
   276  void __sanitizer_cov_trace_pc_guard_init(uint32_t* start, uint32_t* stop) {
   277  
   278    u32 inst_ratio = 100;
   279    u8* x;
   280  
   281    if (start == stop || *start) return;
   282  
   283    x = getenv("AFL_INST_RATIO");
   284    if (x) inst_ratio = atoi(x);
   285  
   286    if (!inst_ratio || inst_ratio > 100) {
   287      fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n");
   288      abort();
   289    }
   290  
   291    /* Make sure that the first element in the range is always set - we use that
   292       to avoid duplicate calls (which can happen as an artifact of the underlying
   293       implementation in LLVM). */
   294  
   295    *(start++) = R(MAP_SIZE - 1) + 1;
   296  
   297    while (start < stop) {
   298  
   299      if (R(100) < inst_ratio) *start = R(MAP_SIZE - 1) + 1;
   300      else *start = 0;
   301  
   302      start++;
   303  
   304    }
   305  
   306  }