#include #include #include #include #include #define STRINGLIT(S) #S #define STRINGIFY(S) STRINGLIT(S) // Required for oss-fuzz to consider the binary a target. static const char* magic __attribute__((used)) = "LLVMFuzzerTestOneInput"; int main(int argc, char* argv[]) { char path[PATH_MAX] = {0}; // Handle (currently not used) relative binary path. if (**argv != '/') { if (!getcwd(path, PATH_MAX - 1)) { perror("getcwd"); exit(1); } strcat(path, "/"); } if (strlen(path) + strlen(*argv) + 40 >= PATH_MAX) { fprintf(stderr, "Path length would exceed PATH_MAX\n"); exit(1); } strcat(path, *argv); char* solidus = strrchr(path, '/'); *solidus = 0; // terminate path before last / char ld_path[PATH_MAX] = {0}; strcpy(ld_path, path); strcat(ld_path, "/lib"); // Expects LD_LIBRARY_PATH to not also be set by oss-fuzz. setenv("LD_LIBRARY_PATH", ld_path, 0); setenv("HOME", "/tmp", 0); setenv("FUZZER", STRINGIFY(FUZZ_TARGET), 1); // ContentParentIPC char blacklist_path[PATH_MAX] = {0}; strcpy(blacklist_path, path); strcat(blacklist_path, "/firefox/libfuzzer.content.blacklist.txt"); setenv("MOZ_IPC_MESSAGE_FUZZ_BLACKLIST", blacklist_path, 1); // Temporary (or permanent?) work-arounds for fuzzing interface bugs. char* options = getenv("ASAN_OPTIONS"); if (options) { char* ptr; char* new_options = strdup(options); // https://bugzilla.mozilla.org/1477846 ptr = strstr(new_options, "detect_stack_use_after_return=1"); if (ptr) ptr[30] = '0'; // https://bugzilla.mozilla.org/1477844 ptr = strstr(new_options, "detect_leaks=1"); if (ptr) ptr[13] = '0'; setenv("ASAN_OPTIONS", new_options, 1); free(new_options); } char ff_path[PATH_MAX] = {0}; strcpy(ff_path, path); strcat(ff_path, "/firefox/firefox"); int ret = execv(ff_path, argv); if (ret) perror("execv"); return ret; }