"Fossies" - the Fresh Open Source Software Archive

Member "honggfuzz-2.2/netbsd/arch.c" (23 Apr 2020, 5630 Bytes) of package /linux/privat/honggfuzz-2.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "arch.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.1_vs_2.2.

    1 /*
    2  *
    3  * honggfuzz - architecture dependent code (NETBSD)
    4  * -----------------------------------------
    5  *
    6  * Author: Kamil Rytarowski <n54@gmx.com>
    7  *
    8  * Copyright 2010-2018 by Google Inc. All Rights Reserved.
    9  *
   10  * Licensed under the Apache License, Version 2.0 (the "License"); you may
   11  * not use this file except in compliance with the License. You may obtain
   12  * a copy of the License at
   13  *
   14  * http://www.apache.org/licenses/LICENSE-2.0
   15  *
   16  * Unless required by applicable law or agreed to in writing, software
   17  * distributed under the License is distributed on an "AS IS" BASIS,
   18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   19  * implied. See the License for the specific language governing
   20  * permissions and limitations under the License.
   21  *
   22  */
   23 
   24 #include "arch.h"
   25 
   26 // clang-format off
   27 #include <sys/param.h>
   28 #include <sys/types.h>
   29 // clang-format on
   30 
   31 #include <sys/ptrace.h>
   32 #include <sys/syscall.h>
   33 #include <sys/time.h>
   34 #include <sys/types.h>
   35 #include <sys/utsname.h>
   36 #include <sys/wait.h>
   37 
   38 #include <ctype.h>
   39 #include <dlfcn.h>
   40 #include <errno.h>
   41 #include <fcntl.h>
   42 #include <inttypes.h>
   43 #include <locale.h>
   44 #include <poll.h>
   45 #include <setjmp.h>
   46 #include <signal.h>
   47 #include <stdio.h>
   48 #include <stdlib.h>
   49 #include <string.h>
   50 #include <time.h>
   51 #include <unistd.h>
   52 
   53 #include "fuzz.h"
   54 #include "libhfcommon/common.h"
   55 #include "libhfcommon/files.h"
   56 #include "libhfcommon/log.h"
   57 #include "libhfcommon/ns.h"
   58 #include "libhfcommon/util.h"
   59 #include "netbsd/trace.h"
   60 #include "subproc.h"
   61 
   62 extern char** environ;
   63 
   64 pid_t arch_fork(run_t* run HF_ATTR_UNUSED) {
   65     pid_t pid = fork();
   66     if (pid == -1) {
   67         return pid;
   68     }
   69     if (pid == 0) {
   70         logMutexReset();
   71         return pid;
   72     }
   73     return pid;
   74 }
   75 
   76 bool arch_launchChild(run_t* run) {
   77     /* alarms persist across execve(), so disable it here */
   78     alarm(0);
   79 
   80     /* Wait for the ptrace to attach now */
   81     if (raise(SIGSTOP) == -1) {
   82         LOG_F("Couldn't stop itself");
   83     }
   84 
   85     execve(run->args[0], (char* const*)run->args, environ);
   86     int errno_cpy = errno;
   87     alarm(1);
   88 
   89     LOG_E("execve('%s'): %s", run->args[0], strerror(errno_cpy));
   90 
   91     return false;
   92 }
   93 
   94 void arch_prepareParentAfterFork(run_t* run) {
   95     /* Parent */
   96     if (run->global->exe.persistent) {
   97         if (fcntl(run->persistentSock, F_SETFL, O_ASYNC) == -1) {
   98             PLOG_F("fcntl(%d, F_SETFL, O_ASYNC)", run->persistentSock);
   99         }
  100     }
  101     if (!arch_traceAttach(run)) {
  102         LOG_F("Couldn't attach to pid=%d", (int)run->pid);
  103     }
  104 }
  105 
  106 void arch_prepareParent(run_t* run HF_ATTR_UNUSED) {
  107 }
  108 
  109 static bool arch_checkWait(run_t* run) {
  110     /* All queued wait events must be tested when SIGCHLD was delivered */
  111     for (;;) {
  112         int status;
  113         /* Wait for the whole process group of run->pid */
  114         pid_t pid = TEMP_FAILURE_RETRY(wait6(P_SID, run->pid, &status,
  115             WALLSIG | WALTSIG | WTRAPPED | WEXITED | WUNTRACED | WCONTINUED | WSTOPPED | WNOHANG,
  116             NULL, NULL));
  117         if (pid == 0) {
  118             return false;
  119         }
  120         if (pid == -1 && errno == ECHILD) {
  121             LOG_D("No more processes to track");
  122             return true;
  123         }
  124         if (pid == -1) {
  125             PLOG_F("wait6(pid/session=%d) failed", (int)run->pid);
  126         }
  127 
  128         arch_traceAnalyze(run, status, pid);
  129 
  130         char statusStr[4096];
  131         LOG_D("pid=%d returned with status: %s", pid,
  132             subproc_StatusToStr(status, statusStr, sizeof(statusStr)));
  133 
  134         if (pid == run->pid && (WIFEXITED(status) || WIFSIGNALED(status))) {
  135             if (run->global->exe.persistent) {
  136                 if (!fuzz_isTerminating()) {
  137                     LOG_W("Persistent mode: PID %d exited with status: %s", pid,
  138                         subproc_StatusToStr(status, statusStr, sizeof(statusStr)));
  139                 }
  140             }
  141             return true;
  142         }
  143     }
  144 }
  145 
  146 void arch_reapChild(run_t* run) {
  147     for (;;) {
  148         if (subproc_persistentModeStateMachine(run)) {
  149             break;
  150         }
  151 
  152         subproc_checkTimeLimit(run);
  153         subproc_checkTermination(run);
  154 
  155         if (run->global->exe.persistent) {
  156             struct pollfd pfd = {
  157                 .fd = run->persistentSock,
  158                 .events = POLLIN,
  159             };
  160             int r = poll(&pfd, 1, 250 /* 0.25s */);
  161             if (r == -1 && errno != EINTR) {
  162                 PLOG_F("poll(fd=%d)", run->persistentSock);
  163             }
  164         } else {
  165             /* Return with SIGIO, SIGCHLD */
  166             const struct timespec ts = {
  167                 .tv_sec = 0ULL,
  168                 .tv_nsec = (1000ULL * 1000ULL * 250ULL),
  169             };
  170             int sig = sigtimedwait(&run->global->exe.waitSigSet, NULL, &ts /* 0.25s */);
  171             if (sig == -1 && (errno != EAGAIN && errno != EINTR)) {
  172                 PLOG_F("sigtimedwait(SIGIO|SIGCHLD)");
  173             }
  174         }
  175 
  176         if (arch_checkWait(run)) {
  177             run->pid = 0;
  178             break;
  179         }
  180     }
  181 }
  182 
  183 bool arch_archInit(honggfuzz_t* hfuzz) {
  184     /* Make %'d work */
  185     setlocale(LC_NUMERIC, "en_US.UTF-8");
  186 
  187     if (access(hfuzz->exe.cmdline[0], X_OK) == -1) {
  188         PLOG_E("File '%s' doesn't seem to be executable", hfuzz->exe.cmdline[0]);
  189         return false;
  190     }
  191 
  192     /* Updates the important signal array based on input args */
  193     arch_traceSignalsInit(hfuzz);
  194 
  195     return true;
  196 }
  197 
  198 bool arch_archThreadInit(run_t* run) {
  199     run->arch_netbsd.perfMmapBuf = NULL;
  200     run->arch_netbsd.perfMmapAux = NULL;
  201     run->arch_netbsd.cpuInstrFd = -1;
  202     run->arch_netbsd.cpuBranchFd = -1;
  203     run->arch_netbsd.cpuIptBtsFd = -1;
  204 
  205     return true;
  206 }