/*
 *
 * honggfuzz - routines dealing with subprocesses
 * -----------------------------------------
 *
 * Author: Robert Swiecki <swiecki@google.com>
 *         Felix Gröbert <groebert@google.com>
 *
 * Copyright 2010-2018 by Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 */

#include "subproc.h"

#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "arch.h"
#include "fuzz.h"
#include "libhfcommon/common.h"
#include "libhfcommon/files.h"
#include "libhfcommon/log.h"
#include "libhfcommon/util.h"

extern char** environ;

const char* subproc_StatusToStr(int status, char* str, size_t len) {
    if (WIFEXITED(status)) {
        snprintf(str, len, "EXITED, exit code: %d", WEXITSTATUS(status));
        return str;
    }

    if (WIFSIGNALED(status)) {
        snprintf(
            str, len, "SIGNALED, signal: %d (%s)", WTERMSIG(status), strsignal(WTERMSIG(status)));
        return str;
    }
    if (WIFCONTINUED(status)) {
        snprintf(str, len, "CONTINUED");
        return str;
    }

    if (!WIFSTOPPED(status)) {
        snprintf(str, len, "UNKNOWN STATUS: %d", status);
        return str;
    }

    /* Must be in a stopped state */
    if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
        snprintf(str, len, "STOPPED (linux syscall): %d (%s)", WSTOPSIG(status),
            strsignal(WSTOPSIG(status)));
        return str;
    }
#if defined(PTRACE_EVENT_STOP)
#define __LINUX_WPTRACEEVENT(x) ((x & 0xff0000) >> 16)
    if (WSTOPSIG(status) == SIGTRAP && __LINUX_WPTRACEEVENT(status) != 0) {
        switch (__LINUX_WPTRACEEVENT(status)) {
            case PTRACE_EVENT_FORK:
                snprintf(str, len, "EVENT (Linux) - fork - with signal: %d (%s)", WSTOPSIG(status),
                    strsignal(WSTOPSIG(status)));
                return str;
            case PTRACE_EVENT_VFORK:
                snprintf(str, len, "EVENT (Linux) - vfork - with signal: %d (%s)", WSTOPSIG(status),
                    strsignal(WSTOPSIG(status)));
                return str;
            case PTRACE_EVENT_CLONE:
                snprintf(str, len, "EVENT (Linux) - clone - with signal: %d (%s)", WSTOPSIG(status),
                    strsignal(WSTOPSIG(status)));
                return str;
            case PTRACE_EVENT_EXEC:
                snprintf(str, len, "EVENT (Linux) - exec - with signal: %d (%s)", WSTOPSIG(status),
                    strsignal(WSTOPSIG(status)));
                return str;
            case PTRACE_EVENT_VFORK_DONE:
                snprintf(str, len, "EVENT (Linux) - vfork_done - with signal: %d (%s)",
                    WSTOPSIG(status), strsignal(WSTOPSIG(status)));
                return str;
            case PTRACE_EVENT_EXIT:
                snprintf(str, len, "EVENT (Linux) - exit - with signal: %d (%s)", WSTOPSIG(status),
                    strsignal(WSTOPSIG(status)));
                return str;
            case PTRACE_EVENT_SECCOMP:
                snprintf(str, len, "EVENT (Linux) - seccomp - with signal: %d (%s)",
                    WSTOPSIG(status), strsignal(WSTOPSIG(status)));
                return str;
            case PTRACE_EVENT_STOP:
                snprintf(str, len, "EVENT (Linux) - stop - with signal: %d (%s)", WSTOPSIG(status),
                    strsignal(WSTOPSIG(status)));
                return str;
            default:
                snprintf(str, len, "EVENT (Linux) UNKNOWN (%d): with signal: %d (%s)",
                    __LINUX_WPTRACEEVENT(status), WSTOPSIG(status), strsignal(WSTOPSIG(status)));
                return str;
        }
    }
#endif /*  defined(PTRACE_EVENT_STOP)  */

    snprintf(
        str, len, "STOPPED with signal: %d (%s)", WSTOPSIG(status), strsignal(WSTOPSIG(status)));
    return str;
}

static bool subproc_persistentSendFileIndicator(run_t* run) {
    uint64_t len = (uint64_t)run->dynamicFileSz;
    if (!files_sendToSocketNB(run->persistentSock, (uint8_t*)&len, sizeof(len))) {
        PLOG_W("files_sendToSocketNB(len=%zu)", sizeof(len));
        return false;
    }
    return true;
}

static bool subproc_persistentGetReady(run_t* run) {
    uint8_t rcv;
    if (recv(run->persistentSock, &rcv, sizeof(rcv), MSG_DONTWAIT) != sizeof(rcv)) {
        return false;
    }
    if (rcv != HFReadyTag) {
        LOG_E("Received invalid message from the persistent process: '%c' (0x%" PRIx8
              ") , expected '%c' (0x%" PRIx8 ")",
            rcv, rcv, HFReadyTag, HFReadyTag);
        return false;
    }
    return true;
}

bool subproc_persistentModeStateMachine(run_t* run) {
    if (!run->global->exe.persistent) {
        return false;
    }

    for (;;) {
        switch (run->runState) {
            case _HF_RS_WAITING_FOR_INITIAL_READY: {
                if (!subproc_persistentGetReady(run)) {
                    return false;
                }
                run->runState = _HF_RS_SEND_DATA;
            }; break;
            case _HF_RS_SEND_DATA: {
                if (!subproc_persistentSendFileIndicator(run)) {
                    LOG_E("Could not send the file size indicator to the persistent process. "
                          "Killing the process pid=%d",
                        (int)run->pid);
                    kill(run->pid, SIGKILL);
                    return false;
                }
                run->runState = _HF_RS_WAITING_FOR_READY;
            }; break;
            case _HF_RS_WAITING_FOR_READY: {
                if (!subproc_persistentGetReady(run)) {
                    return false;
                }
                run->runState = _HF_RS_SEND_DATA;
                /* The current persistent round is done */
                return true;
            }; break;
            default: { LOG_F("Unknown runState: %d", run->runState); }; break;
        }
    }
}

static bool subproc_PrepareExecv(run_t* run) {
    /*
     * The address space limit. If big enough - roughly the size of RAM used
     */
#ifdef RLIMIT_AS
    if (run->global->exe.asLimit) {
        const struct rlimit rl = {
            .rlim_cur = run->global->exe.asLimit * 1024ULL * 1024ULL,
            .rlim_max = run->global->exe.asLimit * 1024ULL * 1024ULL,
        };
        if (setrlimit(RLIMIT_AS, &rl) == -1) {
            PLOG_W("Couldn't enforce the RLIMIT_AS resource limit, ignoring");
        }
    }
#endif /* ifdef RLIMIT_AS */
#ifdef RLIMIT_RSS
    if (run->global->exe.rssLimit) {
        const struct rlimit rl = {
            .rlim_cur = run->global->exe.rssLimit * 1024ULL * 1024ULL,
            .rlim_max = run->global->exe.rssLimit * 1024ULL * 1024ULL,
        };
        if (setrlimit(RLIMIT_RSS, &rl) == -1) {
            PLOG_W("Couldn't enforce the RLIMIT_RSS resource limit, ignoring");
        }
    }
#endif /* ifdef RLIMIT_RSS */
#ifdef RLIMIT_DATA
    if (run->global->exe.dataLimit) {
        const struct rlimit rl = {
            .rlim_cur = run->global->exe.dataLimit * 1024ULL * 1024ULL,
            .rlim_max = run->global->exe.dataLimit * 1024ULL * 1024ULL,
        };
        if (setrlimit(RLIMIT_DATA, &rl) == -1) {
            PLOG_W("Couldn't enforce the RLIMIT_DATA resource limit, ignoring");
        }
    }
#endif /* ifdef RLIMIT_DATA */
#ifdef RLIMIT_CORE
    const struct rlimit rl = {
        .rlim_cur = run->global->exe.coreLimit * 1024ULL * 1024ULL,
        .rlim_max = run->global->exe.coreLimit * 1024ULL * 1024ULL,
    };
    if (setrlimit(RLIMIT_CORE, &rl) == -1) {
        PLOG_W("Couldn't enforce the RLIMIT_CORE resource limit, ignoring");
    }
#endif /* ifdef RLIMIT_CORE */

    if (run->global->exe.clearEnv) {
        environ = NULL;
    }
    for (size_t i = 0; i < ARRAYSIZE(run->global->exe.envs) && run->global->exe.envs[i]; i++) {
        putenv(run->global->exe.envs[i]);
    }
    char fuzzNo[128];
    snprintf(fuzzNo, sizeof(fuzzNo), "%" PRId32, run->fuzzNo);
    setenv(_HF_THREAD_NO_ENV, fuzzNo, 1);
    if (run->global->exe.netDriver) {
        setenv(_HF_THREAD_NETDRIVER_ENV, "1", 1);
    }

    /* Make sure it's a new process group / session, so waitpid can wait for -(run->pid) */
    setsid();

    util_closeStdio(/* close_stdin= */ run->global->exe.nullifyStdio,
        /* close_stdout= */ run->global->exe.nullifyStdio,
        /* close_stderr= */ run->global->exe.nullifyStdio);

    /* The bitmap structure */
    if (run->global->feedback.bbFd != -1 && dup2(run->global->feedback.bbFd, _HF_BITMAP_FD) == -1) {
        PLOG_E("dup2(%d, _HF_BITMAP_FD=%d)", run->global->feedback.bbFd, _HF_BITMAP_FD);
        return false;
    }

    /* The input file to _HF_INPUT_FD */
    if (run->global->exe.persistent && dup2(run->dynamicFileFd, _HF_INPUT_FD) == -1) {
        PLOG_E("dup2('%d', _HF_INPUT_FD='%d')", run->dynamicFileFd, _HF_INPUT_FD);
        return false;
    }

    /* The log FD */
    if ((run->global->exe.netDriver || run->global->exe.persistent)) {
        if (dup2(logFd(), _HF_LOG_FD) == -1) {
            PLOG_E("dup2(%d, _HF_LOG_FD=%d)", logFd(), _HF_LOG_FD);
            return false;
        }
        char llstr[32];
        snprintf(llstr, sizeof(llstr), "%d", logGetLevel());
        setenv(_HF_LOG_LEVEL_ENV, llstr, 1);
    }

    sigset_t sset;
    sigemptyset(&sset);
    if (sigprocmask(SIG_SETMASK, &sset, NULL) == -1) {
        PLOG_W("sigprocmask(empty_set)");
    }

    if (!run->global->exe.persistent) {
        if ((run->dynamicFileCopyFd = files_writeBufToTmpFile(
                 run->global->io.workDir, run->dynamicFile, run->dynamicFileSz, 0)) == -1) {
            LOG_E("Couldn't save data to a temporary file");
            return false;
        }
        if (run->global->exe.fuzzStdin && dup2(run->dynamicFileCopyFd, STDIN_FILENO) == -1) {
            PLOG_E("dup2(_HF_INPUT_FD=%d, STDIN_FILENO=%d)", run->dynamicFileCopyFd, STDIN_FILENO);
            return false;
        }
    }

    return true;
}

static bool subproc_New(run_t* run) {
    if (run->pid) {
        return true;
    }

    int sv[2];
    if (run->global->exe.persistent) {
        if (run->persistentSock != -1) {
            close(run->persistentSock);
        }

        int sock_type = SOCK_STREAM;
#if defined(SOCK_CLOEXEC)
        sock_type |= SOCK_CLOEXEC;
#endif
        if (socketpair(AF_UNIX, sock_type, 0, sv) == -1) {
            PLOG_W("socketpair(AF_UNIX, SOCK_STREAM, 0, sv)");
            return false;
        }
        run->persistentSock = sv[0];
    }

    LOG_D("Forking new process for thread: %" PRId32, run->fuzzNo);

    run->pid = arch_fork(run);
    if (run->pid == -1) {
        PLOG_E("Couldn't fork");
        run->pid = 0;
        return false;
    }
    /* The child process */
    if (!run->pid) {
        logMutexReset();
        /*
         * Reset sighandlers, and set alarm(1). It's a guarantee against dead-locks
         * in the child, where we ensure here that the child process will either
         * execve or get signaled by SIGALRM within 1 second.
         *
         * Those deadlocks typically stem from the fact, that malloc() can behave weirdly
         * when fork()-ing a single thread of a process: e.g. with glibc < 2.24
         * (or, Ubuntu's 2.23-0ubuntu6). For more see
         * http://changelogs.ubuntu.com/changelogs/pool/main/g/glibc/glibc_2.23-0ubuntu7/changelog
         */
        alarm(1);
        signal(SIGALRM, SIG_DFL);

        if (run->global->exe.persistent) {
            if (dup2(sv[1], _HF_PERSISTENT_FD) == -1) {
                PLOG_F("dup2('%d', '%d')", sv[1], _HF_PERSISTENT_FD);
            }
            close(sv[0]);
            close(sv[1]);
        }

        if (!subproc_PrepareExecv(run)) {
            LOG_E("subproc_PrepareExecv() failed");
            exit(EXIT_FAILURE);
        }
        if (!arch_launchChild(run)) {
            LOG_E("Error launching child process");
            kill(run->global->threads.mainPid, SIGTERM);
            _exit(1);
        }
        abort();
    }

    /* Parent */
    LOG_D("Launched new process, pid=%d, thread: %" PRId32 " (concurrency: %zd)", (int)run->pid,
        run->fuzzNo, run->global->threads.threadsMax);

    arch_prepareParentAfterFork(run);

    if (run->global->exe.persistent) {
        close(sv[1]);
        run->runState = _HF_RS_WAITING_FOR_INITIAL_READY;
        LOG_I("Persistent mode: Launched new persistent pid=%d", (int)run->pid);
    }

    return true;
}

bool subproc_Run(run_t* run) {
    run->timeStartedMillis = util_timeNowMillis();

    if (!subproc_New(run)) {
        LOG_E("subproc_New()");
        return false;
    }

    arch_prepareParent(run);
    arch_reapChild(run);

    return true;
}

uint8_t subproc_System(run_t* run, const char* const argv[]) {
    pid_t pid = arch_fork(run);
    if (pid == -1) {
        PLOG_E("Couldn't fork");
        return 255;
    }
    if (!pid) {
        logMutexReset();

        setsid();
        util_closeStdio(
            /* close_stdin= */ true, /* close_stdout= */ false, /* close_stderr= */ false);

        sigset_t sset;
        sigemptyset(&sset);
        if (sigprocmask(SIG_SETMASK, &sset, NULL) == -1) {
            PLOG_W("sigprocmask(empty_set)");
        }

        execv(argv[0], (char* const*)&argv[0]);
        PLOG_F("Couldn't execute '%s'", argv[0]);
        return 255;
    }

    int status;
    int flags = 0;
#if defined(__WNOTHREAD)
    flags |= __WNOTHREAD;
#endif /* defined(__WNOTHREAD) */

    for (;;) {
        int ret = wait4(pid, &status, flags, NULL);
        if (ret == -1 && errno == EINTR) {
            continue;
        }
        if (ret == -1) {
            PLOG_E("wait4() for process pid=%d", (int)pid);
            return 255;
        }
        if (ret != pid) {
            LOG_E("wait4() returned %d, but waited for %d", ret, (int)pid);
            return 255;
        }
        if (WIFSIGNALED(status)) {
            LOG_E("Command '%s' terminated with signal: %d", argv[0], WTERMSIG(status));
            return (100 + WTERMSIG(status));
        }
        if (WIFEXITED(status)) {
            if (WEXITSTATUS(status) == 0) {
                return 0U;
            }
            LOG_E("Command '%s' returned with exit code %d", argv[0], WEXITSTATUS(status));
            return 1U;
        }

        LOG_D("wait4() returned with status: %d", status);
    }
}

void subproc_checkTimeLimit(run_t* run) {
    if (!run->global->timing.tmOut) {
        return;
    }

    int64_t curMillis = util_timeNowMillis();
    int64_t diffMillis = curMillis - run->timeStartedMillis;

    if (run->tmOutSignaled && (diffMillis > ((run->global->timing.tmOut + 1) * 1000))) {
        /* Has this instance been already signaled due to timeout? Just, SIGKILL it */
        LOG_W("pid=%d has already been signaled due to timeout. Killing it with SIGKILL", run->pid);
        kill(run->pid, SIGKILL);
        return;
    }

    if ((diffMillis > (run->global->timing.tmOut * 1000)) && !run->tmOutSignaled) {
        run->tmOutSignaled = true;
        LOG_W("pid=%d took too much time (limit %ld s). Killing it with %s", (int)run->pid,
            (long)run->global->timing.tmOut,
            run->global->timing.tmoutVTALRM ? "SIGVTALRM" : "SIGKILL");
        if (run->global->timing.tmoutVTALRM) {
            kill(run->pid, SIGVTALRM);
        } else {
            kill(run->pid, SIGKILL);
        }
        ATOMIC_POST_INC(run->global->cnts.timeoutedCnt);
    }
}

void subproc_checkTermination(run_t* run) {
    if (fuzz_isTerminating()) {
        LOG_D("Killing pid=%d", (int)run->pid);
        kill(run->pid, SIGKILL);
    }
}
