Distinct directories for each architecture
diff --git a/Makefile b/Makefile
index cef0769..ecfa274 100644
--- a/Makefile
+++ b/Makefile
@@ -33,7 +33,7 @@
OS ?= $(shell uname -s)
-ARCH_SRCS := arch_posix.c
+ARCH_SRCS := $(wildcard posix/*.c)
ifeq ($(OS),Linux)
ifeq ("$(wildcard /usr/include/capstone/capstone.h)","")
@@ -46,7 +46,7 @@
WARN_CAPSTONE =
endif
LDFLAGS += -lcapstone -lunwind-ptrace -lunwind-generic -lbfd
- ARCH_SRCS = arch_linux.c
+ ARCH_SRCS := $(wildcard linux/*.c)
endif
ifeq ($(OS),Darwin)
CC ?= cc
@@ -61,7 +61,7 @@
-framework Foundation -framework ApplicationServices -framework Symbolication \
-framework CoreServices -framework CrashReporterSupport -framework CoreFoundation \
-framework CommerceKit -lm -L/usr/include -L$(shell echo ~)/.homebrew/lib
- ARCH_SRCS = arch_mac.c
+ ARCH_SRCS = $(wildcard mac/*.c)
MIG_OUTPUT = mach_exc.h mach_excUser.c mach_excServer.h mach_excServer.c
MIG_OBJECTS = mach_excUser.o mach_excServer.o
#CRASH_REPORT = third_party/CrashReport_Yosemite.o
@@ -70,10 +70,10 @@
SRCS += $(ARCH_SRCS)
all: $(BIN)
- @echo -ne "$(WARN_CAPSTONE)"
+ @/bin/echo -ne "$(WARN_CAPSTONE)"
.c.o: %.c
- $(CC) $(CFLAGS) $<
+ $(CC) $(CFLAGS) -o $@ $<
$(BIN): $(MIG_OBJECTS) $(OBJS)
$(LD) -o $(BIN) $(OBJS) $(MIG_OBJECTS) $(CRASH_REPORT) $(LDFLAGS)
@@ -89,7 +89,7 @@
$(RM) core $(OBJS) $(BIN) $(MIG_OUTPUT) $(MIG_OBJECTS)
indent:
- indent -linux -l100 -lc100 -nut -i4 -sob -c33 -cp33 *.c *.h; rm -f *~
+ indent -linux -l100 -lc100 -nut -i4 -sob -c33 -cp33 *.c *.h */*.c */*.h; rm -f *~
depend:
makedepend -Y. -- $(SRCS)
diff --git a/common.h b/common.h
index 1d9ecc7..7293373 100644
--- a/common.h
+++ b/common.h
@@ -35,7 +35,7 @@
#define PROG_VERSION "0.4"
#define PROG_AUTHORS "Robert Swiecki <swiecki@google.com> and others, Copyright 2010-2015 by Google Inc. All Rights Reserved."
-#define FILE_PLACEHOLDER "___FILE___"
+#define _HF_FILE_PLACEHOLDER "___FILE___"
typedef struct {
char **cmdline;
@@ -70,4 +70,10 @@
int exception;
} fuzzer_t;
+#define _HF_MAX_FUNCS 200
+typedef struct {
+ void *pc;
+ char func[64];
+} funcs_t;
+
#endif
diff --git a/honggfuzz.c b/honggfuzz.c
index fb32ed2..fdc7fbf 100644
--- a/honggfuzz.c
+++ b/honggfuzz.c
@@ -43,7 +43,7 @@
static bool checkFor_FILE_PLACEHOLDER(char **args)
{
for (int x = 0; args[x]; x++) {
- if (!strcmp(args[x], FILE_PLACEHOLDER))
+ if (!strcmp(args[x], _HF_FILE_PLACEHOLDER))
return true;
}
return false;
@@ -77,7 +77,7 @@
" previously created process, default: '" AB "0" AC "' (none)\n"
#endif /* _HAVE_ARCH_LINUX */
"Usage:"
- AB " " PROG_NAME " -f input_dir -- /usr/bin/tiffinfo -D " FILE_PLACEHOLDER AC "\n");
+ AB " " PROG_NAME " -f input_dir -- /usr/bin/tiffinfo -D " _HF_FILE_PLACEHOLDER AC "\n");
/* *INDENT-ON* */
if (exit_success) {
@@ -187,7 +187,7 @@
if (!hfuzz.fuzzStdin && !checkFor_FILE_PLACEHOLDER(hfuzz.cmdline)) {
LOGMSG(l_FATAL,
- "You must specify '" FILE_PLACEHOLDER
+ "You must specify '" _HF_FILE_PLACEHOLDER
"' when the -s (stdin fuzzing) option is not set");
usage(false);
}
diff --git a/linux/arch.c b/linux/arch.c
new file mode 100644
index 0000000..554c2a5
--- /dev/null
+++ b/linux/arch.c
@@ -0,0 +1,197 @@
+/*
+
+ honggfuzz - architecture dependent code (LINUX)
+ -----------------------------------------
+
+ Author: Robert Swiecki <swiecki@google.com>
+
+ Copyright 2010-2015 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 "common.h"
+#include "arch.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/cdefs.h>
+#include <sys/personality.h>
+#include <sys/ptrace.h>
+#include <sys/prctl.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "linux/ptrace.h"
+#include "log.h"
+#include "util.h"
+
+bool arch_launchChild(honggfuzz_t * hfuzz, char *fileName)
+{
+ if (!arch_ptraceEnable(hfuzz)) {
+ return false;
+ }
+ /*
+ * Kill a process which corrupts its own heap (with ABRT)
+ */
+ if (setenv("MALLOC_CHECK_", "3", 1) == -1) {
+ LOGMSG_P(l_ERROR, "setenv(MALLOC_CHECK_=3) failed");
+ return false;
+ }
+
+ /*
+ * Tell asan to ignore SEGVs
+ */
+ if (setenv("ASAN_OPTIONS", "handle_segv=0", 1) == -1) {
+ LOGMSG_P(l_ERROR, "setenv(ASAN_OPTIONS) failed");
+ return false;
+ }
+
+ /*
+ * Kill the children when fuzzer dies (e.g. due to Ctrl+C)
+ */
+ if (prctl(PR_SET_PDEATHSIG, (long)SIGKILL, 0L, 0L, 0L) == -1) {
+ LOGMSG_P(l_ERROR, "prctl(PR_SET_PDEATHSIG, SIGKILL) failed");
+ return false;
+ }
+
+ /*
+ * Disable ASLR
+ */
+ if (personality(ADDR_NO_RANDOMIZE) == -1) {
+ LOGMSG_P(l_ERROR, "personality(ADDR_NO_RANDOMIZE) failed");
+ return false;
+ }
+#define ARGS_MAX 512
+ char *args[ARGS_MAX + 2];
+
+ int x;
+
+ for (x = 0; x < ARGS_MAX && hfuzz->cmdline[x]; x++) {
+ if (!hfuzz->fuzzStdin && strcmp(hfuzz->cmdline[x], _HF_FILE_PLACEHOLDER) == 0) {
+ args[x] = fileName;
+ } else {
+ args[x] = hfuzz->cmdline[x];
+ }
+ }
+
+ args[x++] = NULL;
+
+ LOGMSG(l_DEBUG, "Launching '%s' on file '%s'", args[0], fileName);
+
+ /*
+ * Set timeout (prof), real timeout (2*prof), and rlimit_cpu (2*prof)
+ */
+ if (hfuzz->tmOut) {
+ /*
+ * The hfuzz->tmOut is real CPU usage time...
+ */
+ struct itimerval it_prof = {
+ .it_interval = {.tv_sec = hfuzz->tmOut,.tv_usec = 0},
+ .it_value = {.tv_sec = 0,.tv_usec = 0}
+ };
+ if (setitimer(ITIMER_PROF, &it_prof, NULL) == -1) {
+ LOGMSG_P(l_ERROR, "Couldn't set the ITIMER_PROF timer");
+ return false;
+ }
+
+ /*
+ * ...so, if a process sleeps, this one should
+ * trigger a signal...
+ */
+ struct itimerval it_real = {
+ .it_interval = {.tv_sec = hfuzz->tmOut * 2UL,.tv_usec = 0},
+ .it_value = {.tv_sec = 0,.tv_usec = 0}
+ };
+ if (setitimer(ITIMER_REAL, &it_real, NULL) == -1) {
+ LOGMSG_P(l_ERROR, "Couldn't set the ITIMER_REAL timer");
+ return false;
+ }
+
+ /*
+ * ..if a process sleeps and catches SIGPROF/SIGALRM
+ * rlimits won't help either
+ */
+ struct rlimit rl = {
+ .rlim_cur = hfuzz->tmOut * 2,
+ .rlim_max = hfuzz->tmOut * 2,
+ };
+ if (setrlimit(RLIMIT_CPU, &rl) == -1) {
+ LOGMSG_P(l_ERROR, "Couldn't enforce the RLIMIT_CPU resource limit");
+ return false;
+ }
+ }
+
+ /*
+ * The address space limit. If big enough - roughly the size of RAM used
+ */
+ if (hfuzz->asLimit) {
+ struct rlimit rl = {
+ .rlim_cur = hfuzz->asLimit * 1024UL * 1024UL,
+ .rlim_max = hfuzz->asLimit * 1024UL * 1024UL,
+ };
+ if (setrlimit(RLIMIT_AS, &rl) == -1) {
+ LOGMSG_P(l_DEBUG, "Couldn't encforce the RLIMIT_AS resource limit, ignoring");
+ }
+ }
+
+ if (hfuzz->nullifyStdio) {
+ util_nullifyStdio();
+ }
+
+ if (hfuzz->fuzzStdin) {
+ /* Uglyyyyyy ;) */
+ if (!util_redirectStdin(fileName)) {
+ return false;
+ }
+ }
+
+ execvp(args[0], args);
+
+ util_recoverStdio();
+ LOGMSG(l_FATAL, "Failed to create new '%s' process", args[0]);
+ return false;
+}
+
+void arch_reapChild(honggfuzz_t * hfuzz, fuzzer_t * fuzzer)
+{
+ int status;
+
+ for (;;) {
+ pid_t pid;
+ while ((pid = wait3(&status, __WNOTHREAD | __WALL | WUNTRACED, NULL)) <= 0) ;
+
+ LOGMSG(l_DEBUG, "Process (pid %d) came back with status %d", pid, status);
+
+ if (arch_ptraceAnalyze(hfuzz, status, pid, fuzzer)) {
+ return;
+ }
+ }
+}
+
+bool arch_prepareParent(honggfuzz_t * hfuzz)
+{
+ return arch_ptracePrepare(hfuzz);
+}
diff --git a/linux/bfd.c b/linux/bfd.c
new file mode 100644
index 0000000..a7db513
--- /dev/null
+++ b/linux/bfd.c
@@ -0,0 +1,115 @@
+/*
+
+ honggfuzz - architecture dependent code (LINUX/BFD)
+ -----------------------------------------
+
+ Author: Robert Swiecki <swiecki@google.com>
+
+ Copyright 2010-2015 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 "common.h"
+#include "linux/bfd.h"
+
+#include <bfd.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+#include "files.h"
+#include "log.h"
+#include "util.h"
+
+static bool arch_bfdInit(pid_t pid, bfd ** bfdh, asection ** section, asymbol *** syms)
+{
+ bfd_init();
+
+ char fname[PATH_MAX];
+ snprintf(fname, sizeof(fname), "/proc/%d/exe", pid);
+
+ *bfdh = bfd_openr(fname, 0);
+ if (*bfdh == NULL) {
+ LOGMSG(l_ERROR, "bfd_openr(%s) failed", fname);
+ return false;
+ }
+
+ if (!bfd_check_format(*bfdh, bfd_object)) {
+ LOGMSG(l_ERROR, "bfd_check_format() failed");
+ return false;
+ }
+
+ int storage_needed = bfd_get_symtab_upper_bound(*bfdh);
+ if (storage_needed <= 0) {
+ LOGMSG(l_ERROR, "bfd_get_symtab_upper_bound() returned '%d'", storage_needed);
+ return false;
+ }
+
+ *syms = (asymbol **) malloc(storage_needed);
+ if (*syms == NULL) {
+ LOGMSG_P(l_ERROR, "malloc(%d) failed", storage_needed);
+ return false;
+ }
+ bfd_canonicalize_symtab(*bfdh, *syms);
+
+ *section = bfd_get_section_by_name(*bfdh, ".text");
+ if (*section == NULL) {
+ LOGMSG(l_ERROR, "bfd_get_section_by_name('.text') failed");
+ return false;
+ }
+
+ return true;
+}
+
+static void arch_bfdDestroy(asymbol ** syms)
+{
+ if (syms) {
+ free(syms);
+ }
+ return;
+}
+
+void arch_bfdResolveSyms(pid_t pid, funcs_t * funcs, size_t num)
+{
+ bfd *bfdh = NULL;
+ asection *section = NULL;
+ asymbol **syms = NULL;
+
+ if (arch_bfdInit(pid, &bfdh, §ion, &syms)) {
+ arch_bfdDestroy(syms);
+ }
+
+ const char *func;
+ const char *file;
+ unsigned int line;
+ for (unsigned int i = 0; i < num; i++) {
+ snprintf(funcs[i].func, sizeof(funcs->func), "[UNKNOWN]");
+ if (funcs[i].pc == NULL) {
+ continue;
+ }
+ long offset = (long)funcs[i].pc - section->vma;
+ if ((offset < 0 || (unsigned long)offset > section->size)) {
+ continue;
+ }
+ if (bfd_find_nearest_line(bfdh, section, syms, offset, &file, &func, &line)) {
+ snprintf(funcs[i].func, sizeof(funcs->func), "%s", func);
+ }
+ }
+
+ arch_bfdDestroy(syms);
+}
diff --git a/linux/bfd.h b/linux/bfd.h
new file mode 100644
index 0000000..78f7f69
--- /dev/null
+++ b/linux/bfd.h
@@ -0,0 +1,29 @@
+/*
+
+ honggfuzz - architecture dependent code
+ -----------------------------------------
+
+ Author: Robert Swiecki <swiecki@google.com>
+
+ Copyright 2010-2015 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.
+
+*/
+
+#ifndef _LINUX_BFD_H_
+#define _LINUX_BFD_H_
+
+extern void arch_bfdResolveSyms(pid_t pid, funcs_t * funcs, size_t num);
+
+#endif
diff --git a/arch_linux.c b/linux/ptrace.c
similarity index 68%
rename from arch_linux.c
rename to linux/ptrace.c
index d926c8e..d3f260c 100644
--- a/arch_linux.c
+++ b/linux/ptrace.c
@@ -22,9 +22,8 @@
*/
#include "common.h"
-#include "arch.h"
+#include "ptrace.h"
-#include <bfd.h>
#include <capstone/capstone.h>
#include <ctype.h>
#include <dirent.h>
@@ -37,7 +36,6 @@
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
-#include <libunwind-ptrace.h>
#include <sys/cdefs.h>
#include <sys/personality.h>
#include <sys/ptrace.h>
@@ -53,6 +51,8 @@
#include <unistd.h>
#include "files.h"
+#include "linux/bfd.h"
+#include "linux/unwind.h"
#include "log.h"
#include "util.h"
@@ -77,110 +77,7 @@
};
/* *INDENT-ON* */
-static bool arch_bfdInit(pid_t pid, bfd ** bfdh, asection ** section, asymbol *** syms)
-{
- bfd_init();
-
- char fname[PATH_MAX];
- snprintf(fname, sizeof(fname), "/proc/%d/exe", pid);
-
- *bfdh = bfd_openr(fname, 0);
- if (*bfdh == NULL) {
- LOGMSG(l_ERROR, "bfd_openr(%s) failed", fname);
- return false;
- }
-
- if (!bfd_check_format(*bfdh, bfd_object)) {
- LOGMSG(l_ERROR, "bfd_check_format() failed");
- return false;
- }
-
- int storage_needed = bfd_get_symtab_upper_bound(*bfdh);
- if (storage_needed <= 0) {
- LOGMSG(l_ERROR, "bfd_get_symtab_upper_bound() returned '%d'", storage_needed);
- return false;
- }
-
- *syms = (asymbol **) malloc(storage_needed);
- if (*syms == NULL) {
- LOGMSG_P(l_ERROR, "malloc(%d) failed", storage_needed);
- return false;
- }
- bfd_canonicalize_symtab(*bfdh, *syms);
-
- *section = bfd_get_section_by_name(*bfdh, ".text");
- if (*section == NULL) {
- LOGMSG(l_ERROR, "bfd_get_section_by_name(.text) failed");
- return false;
- }
-
- return true;
-}
-
-static void arch_unwindPid(pid_t pid, char *newname)
-{
- unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, __BYTE_ORDER);
- if (!as) {
- LOGMSG(l_ERROR, "unw_create_addr_space() failed");
- return;
- }
-
- void *ui = _UPT_create(pid);
- if (ui == NULL) {
- LOGMSG(l_ERROR, "_UPT_create(%d) failed", pid);
- return;
- }
-
- unw_cursor_t c;
- int ret = unw_init_remote(&c, as, ui);
- if (ret != 0) {
- LOGMSG(l_ERROR, "unw_init_remote() failed");
- return;
- }
-
- bfd *bfdh;
- asection *section;
- asymbol **syms;
- bool bfdInitialized = arch_bfdInit(pid, &bfdh, §ion, &syms);
-
- int fd = open("HONGGFUZZ.REPORT.txt", O_CREAT | O_APPEND | O_WRONLY, 0644);
- if (fd == -1) {
- LOGMSG_P(l_ERROR, "Couldn't open 'HONGGFUZZ.REPORT.txt'");
- return;
- }
-
- dprintf(fd, "===========================================\n");
- dprintf(fd, "Input file: %s\n", newname);
-
- while (unw_step(&c) > 0) {
- unw_word_t ip;
- unw_get_reg(&c, UNW_REG_IP, &ip);
-
- dprintf(fd, "[0x%016lx]", (unsigned long)ip);
- if (bfdInitialized) {
- const char *func;
- const char *file;
- unsigned int line;
- long offset = ((long)ip) - section->vma;
- bfd_find_nearest_line(bfdh, section, syms, offset, &file, &func, &line);
- dprintf(fd, " <%s> (line:%d)", func, line);
- }
- dprintf(fd, "\n");
- }
- dprintf(fd, "===========================================\n");
- close(fd);
-
- unw_destroy_addr_space(as);
- _UPT_destroy(ui);
-
- if (syms) {
- free(syms);
- }
-
- return;
-}
-
-static bool arch_enablePtrace(honggfuzz_t * hfuzz)
+bool arch_ptraceEnable(honggfuzz_t * hfuzz)
{
// We're fuzzing an external process, so just return true
if (hfuzz->pid) {
@@ -468,7 +365,7 @@
}
}
-static void arch_savePtraceData(honggfuzz_t * hfuzz, pid_t pid, fuzzer_t * fuzzer)
+static void arch_ptraceSaveData(honggfuzz_t * hfuzz, pid_t pid, fuzzer_t * fuzzer)
{
uint64_t pc = NULL;
@@ -517,14 +414,25 @@
}
}
- arch_unwindPid(pid, newname);
+ funcs_t funcs[_HF_MAX_FUNCS] = {
+ [0 ... (_HF_MAX_FUNCS - 1)].pc = NULL,
+ [0 ... (_HF_MAX_FUNCS - 1)].func = {'\0'}
+ ,
+ };
+
+ size_t num = arch_unwindStack(pid, funcs);
+ arch_bfdResolveSyms(pid, funcs, num);
+
+ for (size_t i = 0; i < num; i++) {
+ LOGMSG(l_ERROR, "PC: %p FUNC: %s", funcs[i].pc, funcs[i].func);
+ }
}
/*
* Returns true if a process exited (so, presumably, we can delete an input
* file)
*/
-static bool arch_analyzePtrace(honggfuzz_t * hfuzz, int status, pid_t pid, fuzzer_t * fuzzer)
+bool arch_ptraceAnalyze(honggfuzz_t * hfuzz, int status, pid_t pid, fuzzer_t * fuzzer)
{
/*
* If it's an uninteresting signal (even SIGTRAP), let it run and relay the
@@ -541,7 +449,7 @@
* the tracer (relay the signal as well)
*/
if (WIFSTOPPED(status) && arch_sigs[WSTOPSIG(status)].important) {
- arch_savePtraceData(hfuzz, pid, fuzzer);
+ arch_ptraceSaveData(hfuzz, pid, fuzzer);
ptrace(PT_CONTINUE, pid, 0, WSTOPSIG(status));
return false;
}
@@ -564,149 +472,6 @@
return true;
}
-bool arch_launchChild(honggfuzz_t * hfuzz, char *fileName)
-{
- if (!arch_enablePtrace(hfuzz)) {
- return false;
- }
- /*
- * Kill a process which corrupts its own heap (with ABRT)
- */
- if (setenv("MALLOC_CHECK_", "3", 1) == -1) {
- LOGMSG_P(l_ERROR, "setenv(MALLOC_CHECK_=3) failed");
- return false;
- }
-
- /*
- * Tell asan to ignore SEGVs
- */
- if (setenv("ASAN_OPTIONS", "handle_segv=0", 1) == -1) {
- LOGMSG_P(l_ERROR, "setenv(ASAN_OPTIONS) failed");
- return false;
- }
-
- /*
- * Kill the children when fuzzer dies (e.g. due to Ctrl+C)
- */
- if (prctl(PR_SET_PDEATHSIG, (long)SIGKILL, 0L, 0L, 0L) == -1) {
- LOGMSG_P(l_ERROR, "prctl(PR_SET_PDEATHSIG, SIGKILL) failed");
- return false;
- }
-
- /*
- * Disable ASLR
- */
- if (personality(ADDR_NO_RANDOMIZE) == -1) {
- LOGMSG_P(l_ERROR, "personality(ADDR_NO_RANDOMIZE) failed");
- return false;
- }
-#define ARGS_MAX 512
- char *args[ARGS_MAX + 2];
-
- int x;
-
- for (x = 0; x < ARGS_MAX && hfuzz->cmdline[x]; x++) {
- if (!hfuzz->fuzzStdin && strcmp(hfuzz->cmdline[x], FILE_PLACEHOLDER) == 0) {
- args[x] = fileName;
- } else {
- args[x] = hfuzz->cmdline[x];
- }
- }
-
- args[x++] = NULL;
-
- LOGMSG(l_DEBUG, "Launching '%s' on file '%s'", args[0], fileName);
-
- /*
- * Set timeout (prof), real timeout (2*prof), and rlimit_cpu (2*prof)
- */
- if (hfuzz->tmOut) {
- /*
- * The hfuzz->tmOut is real CPU usage time...
- */
- struct itimerval it_prof = {
- .it_interval = {.tv_sec = hfuzz->tmOut,.tv_usec = 0},
- .it_value = {.tv_sec = 0,.tv_usec = 0}
- };
- if (setitimer(ITIMER_PROF, &it_prof, NULL) == -1) {
- LOGMSG_P(l_ERROR, "Couldn't set the ITIMER_PROF timer");
- return false;
- }
-
- /*
- * ...so, if a process sleeps, this one should
- * trigger a signal...
- */
- struct itimerval it_real = {
- .it_interval = {.tv_sec = hfuzz->tmOut * 2UL,.tv_usec = 0},
- .it_value = {.tv_sec = 0,.tv_usec = 0}
- };
- if (setitimer(ITIMER_REAL, &it_real, NULL) == -1) {
- LOGMSG_P(l_ERROR, "Couldn't set the ITIMER_REAL timer");
- return false;
- }
-
- /*
- * ..if a process sleeps and catches SIGPROF/SIGALRM
- * rlimits won't help either
- */
- struct rlimit rl = {
- .rlim_cur = hfuzz->tmOut * 2,
- .rlim_max = hfuzz->tmOut * 2,
- };
- if (setrlimit(RLIMIT_CPU, &rl) == -1) {
- LOGMSG_P(l_ERROR, "Couldn't enforce the RLIMIT_CPU resource limit");
- return false;
- }
- }
-
- /*
- * The address space limit. If big enough - roughly the size of RAM used
- */
- if (hfuzz->asLimit) {
- struct rlimit rl = {
- .rlim_cur = hfuzz->asLimit * 1024UL * 1024UL,
- .rlim_max = hfuzz->asLimit * 1024UL * 1024UL,
- };
- if (setrlimit(RLIMIT_AS, &rl) == -1) {
- LOGMSG_P(l_DEBUG, "Couldn't encforce the RLIMIT_AS resource limit, ignoring");
- }
- }
-
- if (hfuzz->nullifyStdio) {
- util_nullifyStdio();
- }
-
- if (hfuzz->fuzzStdin) {
- /* Uglyyyyyy ;) */
- if (!util_redirectStdin(fileName)) {
- return false;
- }
- }
-
- execvp(args[0], args);
-
- util_recoverStdio();
- LOGMSG(l_FATAL, "Failed to create new '%s' process", args[0]);
- return false;
-}
-
-void arch_reapChild(honggfuzz_t * hfuzz, fuzzer_t * fuzzer)
-{
- int status;
-
- for (;;) {
- pid_t pid;
- while ((pid = wait3(&status, __WNOTHREAD | __WALL | WUNTRACED, NULL)) <= 0) ;
-
- LOGMSG(l_DEBUG, "Process (pid %d) came back with status %d", pid, status);
-
- if (arch_analyzePtrace(hfuzz, status, pid, fuzzer)) {
- return;
- }
- }
-}
-
static bool arch_listThreads(int tasks[], size_t thrSz, int pid)
{
size_t count = 0;
@@ -753,7 +518,7 @@
return true;
}
-bool arch_prepareParent(honggfuzz_t * hfuzz)
+bool arch_ptracePrepare(honggfuzz_t * hfuzz)
{
if (!hfuzz->pid) {
return true;
diff --git a/linux/ptrace.h b/linux/ptrace.h
new file mode 100644
index 0000000..75f8200
--- /dev/null
+++ b/linux/ptrace.h
@@ -0,0 +1,31 @@
+/*
+
+ honggfuzz - architecture dependent code
+ -----------------------------------------
+
+ Author: Robert Swiecki <swiecki@google.com>
+
+ Copyright 2010-2015 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.
+
+*/
+
+#ifndef _LINUX_PTRACE_H_
+#define _LINUX_PTRACE_H_
+
+extern bool arch_ptraceEnable(honggfuzz_t * fuzz);
+extern bool arch_ptracePrepare(honggfuzz_t * fuzz);
+extern bool arch_ptraceAnalyze(honggfuzz_t * fuzz, int status, pid_t pid, fuzzer_t * fuzzer);
+
+#endif
diff --git a/linux/unwind.c b/linux/unwind.c
new file mode 100644
index 0000000..1a26b1e
--- /dev/null
+++ b/linux/unwind.c
@@ -0,0 +1,62 @@
+/*
+
+ honggfuzz - architecture dependent code (LINUX/UNWIND)
+ -----------------------------------------
+
+ Author: Robert Swiecki <swiecki@google.com>
+
+ Copyright 2010-2015 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 "common.h"
+#include "linux/unwind.h"
+
+#include <libunwind-ptrace.h>
+
+#include "log.h"
+
+size_t arch_unwindStack(pid_t pid, funcs_t * funcs)
+{
+ unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, __BYTE_ORDER);
+ if (!as) {
+ LOGMSG(l_ERROR, "unw_create_addr_space() failed");
+ return 0U;
+ }
+
+ void *ui = _UPT_create(pid);
+ if (ui == NULL) {
+ LOGMSG(l_ERROR, "_UPT_create(%d) failed", pid);
+ return 0U;
+ }
+
+ unw_cursor_t c;
+ if (unw_init_remote(&c, as, ui) != 0) {
+ LOGMSG(l_ERROR, "unw_init_remote() failed");
+ return 0U;
+ }
+
+ size_t ret = 0;
+ for (ret = 0; unw_step(&c) > 0; ret++) {
+ unw_word_t ip;
+ unw_get_reg(&c, UNW_REG_IP, &ip);
+ funcs[ret].pc = (void *)ip;
+ }
+
+ unw_destroy_addr_space(as);
+ _UPT_destroy(ui);
+
+ return ret;
+}
diff --git a/linux/unwind.h b/linux/unwind.h
new file mode 100644
index 0000000..079570b
--- /dev/null
+++ b/linux/unwind.h
@@ -0,0 +1,29 @@
+/*
+
+ honggfuzz - architecture dependent code
+ -----------------------------------------
+
+ Author: Robert Swiecki <swiecki@google.com>
+
+ Copyright 2010-2015 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.
+
+*/
+
+#ifndef _LINUX_UNWIND_H_
+#define _LINUX_UNWIND_H_
+
+extern size_t arch_unwindStack(pid_t pid, funcs_t * funcs);
+
+#endif
diff --git a/arch_mac.c b/mac/arch_mac.c
similarity index 99%
rename from arch_mac.c
rename to mac/arch_mac.c
index 906569c..4fcf2d4 100644
--- a/arch_mac.c
+++ b/mac/arch_mac.c
@@ -224,7 +224,7 @@
int x;
for (x = 0; x < ARGS_MAX && hfuzz->cmdline[x]; x++) {
- if (!hfuzz->fuzzStdin && strcmp(hfuzz->cmdline[x], FILE_PLACEHOLDER) == 0) {
+ if (!hfuzz->fuzzStdin && strcmp(hfuzz->cmdline[x], _HF_FILE_PLACEHOLDER) == 0) {
args[x] = fileName;
} else {
args[x] = hfuzz->cmdline[x];
diff --git a/arch_posix.c b/posix/arch_posix.c
similarity index 98%
rename from arch_posix.c
rename to posix/arch_posix.c
index 4d14797..847eaa7 100644
--- a/arch_posix.c
+++ b/posix/arch_posix.c
@@ -128,7 +128,7 @@
int x;
for (x = 0; x < ARGS_MAX && hfuzz->cmdline[x]; x++) {
- if (!hfuzz->fuzzStdin && strcmp(hfuzz->cmdline[x], FILE_PLACEHOLDER) == 0) {
+ if (!hfuzz->fuzzStdin && strcmp(hfuzz->cmdline[x], _HF_FILE_PLACEHOLDER) == 0) {
args[x] = fileName;
} else {
args[x] = hfuzz->cmdline[x];