Ejemplo n.º 1
0
void arch_reapChild(honggfuzz_t * hfuzz, fuzzer_t * fuzzer)
{
    timer_t timerid;
    if (arch_setTimer(&timerid) == false) {
        LOGMSG(l_FATAL, "Couldn't set timer");
    }

    int perfFd[3];
    if (hfuzz->pid == 0) {
        int status;
        pid_t pid = wait4(fuzzer->pid, &status, __WNOTHREAD | __WALL | WUNTRACED, NULL);
        if (pid != pid) {
            LOGMSG(l_FATAL, "wait4() =! pid (%d)", fuzzer->pid);
        }
        if (!WIFSTOPPED(status)) {
            LOGMSG(l_FATAL, "PID '%d' is not in a stopped state", fuzzer->pid);
        }
        if (arch_ptraceAttach(fuzzer->pid) == false) {
            LOGMSG(l_FATAL, "Couldn't attach to pid %d", fuzzer->pid);
        }
        if (arch_perfEnable(fuzzer->pid, hfuzz, perfFd) == false) {
            LOGMSG(l_FATAL, "Couldn't enable perf counters for pid %d", fuzzer->pid);
        }
        arch_ptraceAnalyze(hfuzz, status, fuzzer->pid, fuzzer);
    }

    for (;;) {
        int status;
        pid_t pid = wait3(&status, __WNOTHREAD | __WALL | WUNTRACED, NULL);

        LOGMSG(l_DEBUG, "PID '%d' returned with status '%d'", pid, status);

        if (pid == -1 && errno == EINTR) {
            arch_checkTimeLimit(hfuzz, fuzzer);
            continue;
        }
        if (pid == -1 && errno == ECHILD) {
            if (hfuzz->pid == 0) {
                arch_perfAnalyze(hfuzz, fuzzer, perfFd);
            }
            LOGMSG(l_DEBUG, "No more processes to track");
            arch_removeTimer(&timerid);
            return;
        }
        if (pid == -1) {
            LOGMSG_P(l_FATAL, "wait3() failed");
        }

        if (hfuzz->pid == 0) {
            uint64_t tmp = arch_ptraceGetCustomPerf(hfuzz, pid);
            if (tmp != 0ULL) {
                fuzzer->branchCnt[3] = tmp;
            }
            arch_ptraceAnalyze(hfuzz, status, pid, fuzzer);
        }
    }
}
Ejemplo n.º 2
0
void arch_reapChild(honggfuzz_t * hfuzz, fuzzer_t * fuzzer)
{
    pid_t ptracePid = (hfuzz->pid > 0) ? hfuzz->pid : fuzzer->pid;
    pid_t childPid = fuzzer->pid;

    timer_t timerid;
    if (arch_setTimer(&timerid) == false) {
        LOG_F("Couldn't set timer");
    }

    if (arch_ptraceWaitForPidStop(childPid) == false) {
        LOG_F("PID %d not in a stopped state", childPid);
    }
    LOG_D("PID: %d is in a stopped state now", childPid);

    static bool ptraceAttached = false;
    if (ptraceAttached == false) {
        if (arch_ptraceAttach(ptracePid) == false) {
            LOG_F("arch_ptraceAttach(pid=%d) failed", ptracePid);
        }
        /* In case we fuzz a long-lived process (-p pid) we attach to it once only */
        if (ptracePid != childPid) {
            ptraceAttached = true;
        }
    }
    /* A long-lived processed could have already exited, and we wouldn't know */
    if (kill(ptracePid, 0) == -1) {
        PLOG_F("Liveness of %d questioned", ptracePid);
    }

    perfFd_t perfFds;
    if (arch_perfEnable(ptracePid, hfuzz, &perfFds) == false) {
        LOG_F("Couldn't enable perf counters for pid %d", ptracePid);
    }
    if (kill(childPid, SIGCONT) == -1) {
        PLOG_F("Restarting PID: %d failed", childPid);
    }

    for (;;) {
        int status;
        pid_t pid = wait4(-1, &status, __WALL | __WNOTHREAD, NULL);
        if (pid == -1 && errno == EINTR) {
            if (hfuzz->tmOut) {
                arch_checkTimeLimit(hfuzz, fuzzer);
            }
            continue;
        }
        if (pid == -1 && errno == ECHILD) {
            LOG_D("No more processes to track");
            break;
        }
        if (pid == -1) {
            PLOG_F("wait4() failed");
        }
        LOG_D("PID '%d' returned with status '%d'", pid, status);

        arch_ptraceGetCustomPerf(hfuzz, ptracePid, &fuzzer->hwCnts.customCnt);

        if (ptracePid == childPid) {
            arch_ptraceAnalyze(hfuzz, status, pid, fuzzer);
            continue;
        }
        if (pid == childPid && (WIFEXITED(status) || WIFSIGNALED(status))) {
            break;
        }
        if (pid == childPid) {
            continue;
        }

        arch_ptraceAnalyze(hfuzz, status, pid, fuzzer);
    }
    arch_removeTimer(&timerid);
    arch_perfAnalyze(hfuzz, fuzzer, &perfFds);
    return;
}