예제 #1
0
파일: util.c 프로젝트: naisanza/honggfuzz
uint64_t util_rndGet(uint64_t min, uint64_t max)
{
    if (min > max) {
        LOG_F("min:%" PRIu64 " > max:%" PRIu64, min, max);
    }

    if (util_urandomFd == -1) {
        if ((util_urandomFd = open("/dev/urandom", O_RDONLY)) == -1) {
            PLOG_F("Couldn't open /dev/urandom for writing");
        }
    }

    if (rndIni == false) {
        if (files_readFromFd(util_urandomFd, (uint8_t *) & rndX, sizeof(rndX)) == false) {
            PLOG_F("Couldn't read '%zu' bytes from /dev/urandom", sizeof(rndX));
        }
        rndIni = true;
    }

    /* MMIX LCG PRNG */
    static const uint64_t a = 6364136223846793005ULL;
    static const uint64_t c = 1442695040888963407ULL;

    rndX = (a * rndX + c);

    return ((rndX % (max - min + 1)) + min);
}
예제 #2
0
파일: arch.c 프로젝트: 55-AA/honggfuzz
pid_t arch_fork(honggfuzz_t * hfuzz, fuzzer_t * fuzzer)
{
    int sv[2];
    if (hfuzz->persistent == true) {
        close(fuzzer->linux.persistentSock);
        if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
            LOG_F("socketpair(AF_UNIX, SOCK_STREAM)");
            return -1;
        }
    }

    /*
     * We need to wait for the child to finish with wait() in case we're fuzzing
     * an external process
     */
    uintptr_t clone_flags = CLONE_UNTRACED;
    if (hfuzz->linux.pid) {
        clone_flags = SIGCHLD;
    }

    pid_t pid = syscall(__NR_clone, (uintptr_t) clone_flags, NULL, NULL, NULL, (uintptr_t) 0);

    if (hfuzz->persistent == true) {
        if (pid == -1) {
            close(sv[0]);
            close(sv[1]);
        }
        if (pid == 0) {
            if (dup2(sv[1], 1023) == -1) {
                PLOG_F("dup2('%d', '%d')", sv[1], 1023);
            }
            close(sv[0]);
            close(sv[1]);
        }
        if (pid > 0) {
            close(sv[1]);
            fuzzer->linux.persistentSock = sv[0];
            struct f_owner_ex fown = {.type = F_OWNER_TID,.pid = syscall(__NR_gettid), };
            if (fcntl(fuzzer->linux.persistentSock, F_SETOWN_EX, &fown)) {
                PLOG_F("fcntl(%d, F_SETOWN_EX)", fuzzer->linux.persistentSock);
            }
            if (fcntl(fuzzer->linux.persistentSock, F_SETSIG, SIGNAL_WAKE) == -1) {
                PLOG_F("fcntl(%d, F_SETSIG, SIGNAL_WAKE)", fuzzer->linux.persistentSock);
            }
            if (fcntl(fuzzer->linux.persistentSock, F_SETFL, O_ASYNC) == -1) {
                PLOG_F("fcntl(%d, F_SETFL, O_ASYNC)", fuzzer->linux.persistentSock);
            }
        }
    }
예제 #3
0
파일: nsjail.c 프로젝트: Gardenya/nsjail
int main(int argc, char *argv[])
{
	struct nsjconf_t nsjconf;
	if (!cmdlineParse(argc, argv, &nsjconf)) {
		exit(1);
	}
	if (nsjconf.clone_newuser == false && geteuid() != 0) {
		LOG_W("--disable_clone_newuser requires root() privs");
	}
	if (nsjconf.daemonize && (daemon(0, 0) == -1)) {
		PLOG_F("daemon");
	}
	cmdlineLogParams(&nsjconf);
	if (nsjailSetSigHandlers() == false) {
		exit(1);
	}
	if (nsjailSetTimer() == false) {
		exit(1);
	}

	if (nsjconf.mode == MODE_LISTEN_TCP) {
		nsjailListenMode(&nsjconf);
	} else {
		return nsjailStandaloneMode(&nsjconf);
	}
	return 0;
}
예제 #4
0
파일: util.c 프로젝트: naisanza/honggfuzz
extern int64_t util_timeNowMillis(void)
{
    struct timeval tv;
    if (gettimeofday(&tv, NULL) == -1) {
        PLOG_F("gettimeofday()");
    }

    return (((int64_t) tv.tv_sec * 1000LL) + ((int64_t) tv.tv_usec / 1000LL));
}
예제 #5
0
파일: cmdline.c 프로젝트: google/honggfuzz
rlim_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul) {
    struct rlimit cur;
    if (getrlimit(res, &cur) == -1) {
        PLOG_F("getrlimit(%d)", res);
    }
    if (strcasecmp(optarg, "max") == 0) {
        return cur.rlim_max;
    }
    if (strcasecmp(optarg, "def") == 0) {
        return cur.rlim_cur;
    }
    if (util_isANumber(optarg) == false) {
        LOG_F("RLIMIT %d needs a numeric or 'max'/'def' value ('%s' provided)", res, optarg);
    }
    rlim_t val = strtoul(optarg, NULL, 0) * mul;
    if ((unsigned long)val == ULONG_MAX && errno != 0) {
        PLOG_F("strtoul('%s', 0)", optarg);
    }
    return val;
}
예제 #6
0
bool arch_archInit(honggfuzz_t * hfuzz)
{
    if (hfuzz->dynFileMethod != _HF_DYNFILE_NONE) {
        unsigned long major = 0, minor = 0;
        char *p = NULL;

        /*
         * Check that Linux kernel is compatible
         *
         * Compatibility list:
         *  1) Perf exclude_callchain_kernel requires kernel >= 3.7
         *     TODO: Runtime logic to disable it for unsupported kernels
         *           if it doesn't affect perf counters processing
         *  2) If 'PERF_TYPE_HARDWARE' is not supported by kernel, ENOENT
         *     is returned from perf_event_open(). Unfortunately, no reliable
         *     way to detect it here. libperf exports some list functions,
         *     although small guarantees it's installed. Maybe a more targeted 
         *     message at perf_event_open() error handling will help.
         */
        struct utsname uts;
        if (uname(&uts) == -1) {
            PLOG_F("uname() failed");
            return false;
        }

        p = uts.release;
        major = strtoul(p, &p, 10);
        if (*p++ != '.') {
            LOG_F("Unsupported kernel version (%s)", uts.release);
            return false;
        }

        minor = strtoul(p, &p, 10);
        if ((major < 3) || ((major == 3) && (minor < 7))) {
            LOG_E("Unsupported kernel version (%s)", uts.release);
            return false;
        }
    }
#if defined(__ANDROID__) && defined(__arm__)
    /* 
     * For ARM kernels running Android API <= 21, if fuzzing target links to 
     * libcrypto (OpenSSL), OPENSSL_cpuid_setup initialization is triggering a
     * SIGILL/ILLOPC at armv7_tick() due to  "mrrc p15, #1, r0, r1, c14)" instruction.
     * Setups using BoringSSL (API >= 22) are not affected.
     */
    if (setenv("OPENSSL_armcap", OPENSSL_ARMCAP_ABI, 1) == -1) {
        PLOG_E("setenv(OPENSSL_armcap) failed");
        return false;
    }
#endif

    return true;
}
예제 #7
0
파일: report.c 프로젝트: google/honggfuzz
void report_Report(run_t* run) {
    if (run->report[0] == '\0') {
        return;
    }

    MX_SCOPED_LOCK(&run->global->cfg.report_mutex);

    if (reportFD == -1) {
        char reportFName[PATH_MAX];
        if (run->global->cfg.reportFile == NULL) {
            snprintf(reportFName, sizeof(reportFName), "%s/%s", run->global->io.workDir,
                _HF_REPORT_FILE);
        } else {
            snprintf(reportFName, sizeof(reportFName), "%s", run->global->cfg.reportFile);
        }

        reportFD =
            TEMP_FAILURE_RETRY(open(reportFName, O_WRONLY | O_CREAT | O_APPEND | O_CLOEXEC, 0644));
        if (reportFD == -1) {
            PLOG_F("Couldn't open('%s') for writing", reportFName);
        }
    }

    char localtmstr[PATH_MAX];
    util_getLocalTime("%F.%H:%M:%S", localtmstr, sizeof(localtmstr), time(NULL));

    dprintf(reportFD,
        "=====================================================================\n"
        "TIME: %s\n"
        "=====================================================================\n"
        "FUZZER ARGS:\n"
        " mutationsPerRun : %u\n"
        " externalCmd     : %s\n"
        " fuzzStdin       : %s\n"
        " timeout         : %ld (sec)\n"
#if defined(_HF_ARCH_LINUX) || defined(_HF_ARCH_NETBSD)
        " ignoreAddr      : %p\n"
#endif
        " ASLimit         : %" PRIu64 " (MiB)\n"
        " RSSLimit        : %" PRIu64 " (MiB)\n"
        " DATALimit       : %" PRIu64 " (MiB)\n"
        " wordlistFile    : %s\n",
        localtmstr, run->global->mutate.mutationsPerRun,
        run->global->exe.externalCommand == NULL ? "NULL" : run->global->exe.externalCommand,
        run->global->exe.fuzzStdin ? "TRUE" : "FALSE", run->global->timing.tmOut,
#if defined(_HF_ARCH_LINUX)
        run->global->linux.ignoreAddr,
#elif defined(_HF_ARCH_NETBSD)
        run->global->netbsd.ignoreAddr,
#endif
        run->global->exe.asLimit, run->global->exe.rssLimit, run->global->exe.dataLimit,
        run->global->mutate.dictionaryFile == NULL ? "NULL" : run->global->mutate.dictionaryFile);

#if defined(_HF_ARCH_LINUX)
    report_printdynFileMethod(run);
#endif

    report_printTargetCmd(run);

    dprintf(reportFD,
        "%s"
        "=====================================================================\n",
        run->report);
}
예제 #8
0
파일: perf.c 프로젝트: quangnh89/honggfuzz
static bool arch_perfOpen(pid_t pid, dynFileMethod_t method, int *perfFd)
{
    LOG_D("Enabling PERF for PID=%d (mmapBufSz=%zu), method=%x", pid, perfMmapSz, method);

    perfDynamicMethod = method;
    perfBranchesCnt = 0;
    perfRecordsLost = 0;

    struct perf_event_attr pe;
    memset(&pe, 0, sizeof(struct perf_event_attr));
    pe.size = sizeof(struct perf_event_attr);
    pe.disabled = 0;
    pe.exclude_kernel = 1;
    pe.exclude_hv = 1;
    pe.exclude_callchain_kernel = 1;
    pe.enable_on_exec = 1;
    pe.type = PERF_TYPE_HARDWARE;

    switch (method) {
    case _HF_DYNFILE_INSTR_COUNT:
        LOG_D("Using: PERF_COUNT_HW_INSTRUCTIONS for PID: %d", pid);
        pe.config = PERF_COUNT_HW_INSTRUCTIONS;
        pe.inherit = 1;
        break;
    case _HF_DYNFILE_BRANCH_COUNT:
        LOG_D("Using: PERF_COUNT_HW_BRANCH_INSTRUCTIONS for PID: %d", pid);
        pe.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
        pe.inherit = 1;
        break;
    case _HF_DYNFILE_UNIQUE_BLOCK_COUNT:
        LOG_D("Using: PERF_SAMPLE_BRANCH_STACK/PERF_SAMPLE_IP for PID: %d", pid);
        pe.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
        pe.sample_type = PERF_SAMPLE_IP;
        pe.sample_period = 1;   /* It's BTS based, so must be equal to 1 */
        pe.watermark = 1;
        pe.wakeup_events = perfMmapSz / 2;
        break;
    case _HF_DYNFILE_UNIQUE_EDGE_COUNT:
        LOG_D("Using: PERF_SAMPLE_BRANCH_STACK/PERF_SAMPLE_IP|PERF_SAMPLE_ADDR for PID: %d", pid);
        pe.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
        pe.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_ADDR;
        pe.sample_period = 1;   /* It's BTS based, so must be equal to 1 */
        pe.watermark = 1;
        pe.wakeup_events = perfMmapSz / 2;
        break;
    default:
        LOG_E("Unknown perf mode: '%d' for PID: %d", method, pid);
        return false;
        break;
    }

    *perfFd = perf_event_open(&pe, pid, -1, -1, 0);
    if (*perfFd == -1) {
        if (method == _HF_DYNFILE_UNIQUE_BLOCK_COUNT || method == _HF_DYNFILE_UNIQUE_EDGE_COUNT) {
            LOG_E
                ("'-LDp'/'-LDe' mode (sample IP/jump) requires LBR/BTS, which present in Intel Haswell "
                 "and newer CPUs (i.e. not in AMD CPUs)");
        }
        PLOG_F("perf_event_open() failed");
        return false;
    }

    if (method != _HF_DYNFILE_UNIQUE_BLOCK_COUNT && method != _HF_DYNFILE_UNIQUE_EDGE_COUNT) {
        return true;
    }

    perfBloom = mmap(NULL, _HF_PERF_BLOOM_SZ, PROT_READ | PROT_WRITE,
                     MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
    if (perfBloom == MAP_FAILED) {
        perfBloom = NULL;
        PLOG_E("mmap(size=%zu) failed", (size_t) _HF_PERF_BLOOM_SZ);
    }

    perfMmapBuf =
        mmap(NULL, perfMmapSz + getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, *perfFd, 0);
    if (perfMmapBuf == MAP_FAILED) {
        perfMmapBuf = NULL;
        PLOG_E("mmap() failed");
        close(*perfFd);
        return false;
    }

    struct sigaction sa = {
        .sa_handler = arch_perfSigHandler,
        .sa_flags = SA_RESTART,
    };
    sigemptyset(&sa.sa_mask);
    if (sigaction(_HF_RT_SIG, &sa, NULL) == -1) {
        PLOG_E("sigaction() failed");
        return false;
    }
    if (fcntl(*perfFd, F_SETFL, O_RDWR | O_NONBLOCK | O_ASYNC) == -1) {
        PLOG_E("fnctl(F_SETFL)");
        close(*perfFd);
        return false;
    }
    if (fcntl(*perfFd, F_SETSIG, _HF_RT_SIG) == -1) {
        PLOG_E("fnctl(F_SETSIG)");
        close(*perfFd);
        return false;
    }
    struct f_owner_ex foe = {
        .type = F_OWNER_TID,
        .pid = syscall(__NR_gettid)
    };
    if (fcntl(*perfFd, F_SETOWN_EX, &foe) == -1) {
        PLOG_E("fnctl(F_SETOWN_EX)");
        close(*perfFd);
        return false;
    }
    return true;
}
예제 #9
0
파일: util.c 프로젝트: naisanza/honggfuzz
extern void MX_UNLOCK(pthread_mutex_t * mutex)
{
    if (pthread_mutex_unlock(mutex)) {
        PLOG_F("pthread_mutex_unlock(%p)", mutex);
    }
}
예제 #10
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;
}
예제 #11
0
파일: nsjail.c 프로젝트: Abioy/nsjail
int main(int argc, char *argv[])
{
	struct nsjconf_t nsjconf = {
		.hostname = "NSJAIL",
		.chroot = "/chroot",
		.argv = NULL,
		.port = 31337,
		.uid = -1,
		.gid = -1,
		.daemonize = false,
		.tlimit = 0,
		.apply_sandbox = true,
		.verbose = false,
		.keep_caps = false,
		.rl_as = 512 * (1024 * 1024),
		.rl_core = 0,
		.rl_cpu = 600,
		.rl_fsize = 1 * (1024 * 1024),
		.rl_nofile = 32,
		.rl_nproc = cmdlineParseRLimit(RLIMIT_NPROC, "def", 1),
		.rl_stack = cmdlineParseRLimit(RLIMIT_STACK, "def", 1),
		.personality = 0,
		.clone_newnet = true,
		.clone_newuser = true,
		.clone_newns = true,
		.clone_newpid = true,
		.clone_newipc = true,
		.clone_newuts = true,
		.mode = MODE_LISTEN_TCP,
		.is_root_rw = false,
		.is_silent = false,
		.bindmountpts = NULL,
		.tmpfsmountpts = NULL,
		.initial_uid = getuid(),
		.initial_gid = getgid(),
		.max_conns_per_ip = 0,
	};

	if (!cmdlineParse(argc, argv, &nsjconf)) {
		exit(1);
	}
	if (nsjconf.clone_newuser == false && geteuid() != 0) {
		LOG_E("--disable_clone_newuser requires root() privs");
	}
	if (nsjconf.daemonize && (daemon(0, 0) == -1)) {
		PLOG_F("daemon");
	}
	cmdlineLogParams(&nsjconf);
	if (nsjailSetSigHandlers() == false) {
		exit(1);
	}
	if (nsjailSetTimer() == false) {
		exit(1);
	}

	if (nsjconf.mode == MODE_LISTEN_TCP) {
		nsjailListenMode(&nsjconf);
	} else {
		nsjailStandaloneMode(&nsjconf);
	}
	return 0;
}
예제 #12
0
파일: fuzz.c 프로젝트: quangnh89/honggfuzz
static bool fuzz_prepareFileExternally(honggfuzz_t * hfuzz, fuzzer_t * fuzzer, int rnd_index)
{
    int dstfd = open(fuzzer->fileName, O_CREAT | O_EXCL | O_RDWR, 0644);
    if (dstfd == -1) {
        PLOG_E("Couldn't create a temporary file '%s'", fuzzer->fileName);
        return false;
    }

    LOG_D("Created '%s' as an input file", fuzzer->fileName);

    if (hfuzz->inputFile) {
        size_t fileSz =
            files_readFileToBufMax(hfuzz->files[rnd_index], fuzzer->dynamicFile, hfuzz->maxFileSz);
        if (fileSz == 0UL) {
            LOG_E("Couldn't read '%s'", hfuzz->files[rnd_index]);
            unlink(fuzzer->fileName);
            return false;
        }

        if (files_writeToFd(dstfd, fuzzer->dynamicFile, fileSz) == false) {
            close(dstfd);
            unlink(fuzzer->fileName);
            return false;
        }
    }

    close(dstfd);

    pid_t pid = arch_fork(hfuzz);
    if (pid == -1) {
        PLOG_E("Couldn't fork");
        return false;
    }

    if (!pid) {
        /*
         * child performs the external file modifications
         */
        execl(hfuzz->externalCommand, hfuzz->externalCommand, fuzzer->fileName, NULL);
        PLOG_F("Couldn't execute '%s %s'", hfuzz->externalCommand, fuzzer->fileName);
        return false;
    }

    /*
     * parent waits until child is done fuzzing the input file
     */
    int childStatus;
    int flags = 0;
#if defined(__WNOTHREAD)
    flags |= __WNOTHREAD;
#endif                          /* defined(__WNOTHREAD) */
    while (wait4(pid, &childStatus, flags, NULL) != pid) ;
    if (WIFEXITED(childStatus)) {
        LOG_D("External command exited with status %d", WEXITSTATUS(childStatus));
        return true;
    }
    if (WIFSIGNALED(childStatus)) {
        LOG_E("External command terminated with signal %d", WTERMSIG(childStatus));
        return false;
    }
    LOG_F("External command terminated abnormally, status: %d", childStatus);
    return false;

    abort();                    /* NOTREACHED */
}