static int register_command_handler(struct command_context *cmd_ctx, struct command *c) { Jim_Interp *interp = cmd_ctx->interp; char *ocd_name = alloc_printf("ocd_%s", c->name); if (NULL == ocd_name) return JIM_ERR; LOG_DEBUG("registering '%s'...", ocd_name); Jim_CmdProc *func = c->handler ? &script_command : &command_unknown; int retval = Jim_CreateCommand(interp, ocd_name, func, c, NULL); free(ocd_name); if (JIM_OK != retval) return retval; /* we now need to add an overrideable proc */ char *override_name = alloc_printf( "proc %s {args} {eval ocd_bouncer %s $args}", c->name, c->name); if (NULL == override_name) return JIM_ERR; retval = Jim_Eval_Named(interp, override_name, 0, 0); free(override_name); return retval; }
int main (void) { char * chaine; char * seizecars = "0123456789ABCDEF"; chaine = alloc_printf (" %s %s", seizecars, seizecars, seizecars, seizecars); if (chaine != NULL) { fprintf (stdout, "Chaine de %d caractères\n%s\n", strlen (chaine), chaine); free (chaine); } chaine = alloc_printf (" %s %s %s %s", seizecars, seizecars, seizecars, seizecars); if (chaine != NULL) { fprintf (stdout, "Chaine de %d caractères\n%s\n", strlen (chaine), chaine); free (chaine); } return (0); }
/* return full path or NULL according to search rules */ char *find_file(const char *file) { FILE *fp = NULL; char **search_dirs = script_search_dirs; char *dir; char const *mode = "r"; char *full_path; /* Check absolute and relative to current working dir first. * This keeps full_path reporting belowing working. */ full_path = alloc_printf("%s", file); fp = fopen(full_path, mode); while (!fp) { free(full_path); full_path = NULL; dir = *search_dirs++; if (!dir) break; full_path = alloc_printf("%s/%s", dir, file); fp = fopen(full_path, mode); } if (fp) { fclose(fp); LOG_DEBUG("found %s", full_path); return full_path; } free(full_path); return NULL; }
static void test_alloc_vprintf(void) { char buf[MG_BUF_LEN], *p = buf; ASSERT(alloc_printf(&p, sizeof(buf), "%s", "hi") == 2); ASSERT(p == buf); ASSERT(alloc_printf(&p, sizeof(buf), "%s", "") == 0); ASSERT(alloc_printf(&p, sizeof(buf), "") == 0); // Pass small buffer, make sure alloc_printf allocates ASSERT(alloc_printf(&p, 1, "%s", "hello") == 5); ASSERT(p != buf); free(p); }
static void find_obj(u8* argv0) { u8 *afl_path = getenv("AFL_PATH"); u8 *slash, *tmp; if (afl_path) { tmp = alloc_printf("%s/afl-llvm-rt.o", afl_path); if (!access(tmp, R_OK)) { obj_path = afl_path; ck_free(tmp); return; } ck_free(tmp); } slash = strrchr(argv0, '/'); if (slash) { u8 *dir; *slash = 0; dir = ck_strdup(argv0); *slash = '/'; tmp = alloc_printf("%s/afl-llvm-rt.o", dir); if (!access(tmp, R_OK)) { obj_path = dir; ck_free(tmp); return; } ck_free(tmp); ck_free(dir); } if (!access(AFL_PATH "/afl-llvm-rt.o", R_OK)) { obj_path = AFL_PATH; return; } FATAL("Unable to find 'afl-llvm-rt.o' or 'afl-llvm-pass.so'. Please set AFL_PATH"); }
void get_exit_status(int status, char **exit_status, int *exit_code) { if (WIFEXITED(status)) { *exit_status = alloc_printf("exited with code %d", WEXITSTATUS(status)); if (exit_code) *exit_code = WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { if(WCOREDUMP(status)) *exit_status = alloc_printf("terminated by signal %d (core dumped)", WTERMSIG(status)); else *exit_status = alloc_printf("terminated by signal %d (no core dump)", WTERMSIG(status)); } else *exit_status = alloc_printf("exited for unknown reason (no exit code or singal)"); }
static void test_mg_upload(void) { static const char *boundary = "OOO___MY_BOUNDARY___OOO"; struct mg_context *ctx; struct mg_connection *conn; char ebuf[100], buf[20], *file_data, *post_data = NULL; int file_len, post_data_len; ASSERT((ctx = mg_start(&CALLBACKS, NULL, OPTIONS)) != NULL); ASSERT((file_data = read_file("mongoose.c", &file_len)) != NULL); post_data_len = alloc_printf(&post_data, 0, "--%s\r\n" "Content-Disposition: form-data; " "name=\"file\"; " "filename=\"%s\"\r\n\r\n" "%.*s\r\n" "--%s\r\n", boundary, upload_filename, file_len, file_data, boundary); ASSERT(post_data_len > 0); ASSERT((conn = mg_download("localhost", atoi(HTTPS_PORT), 1, ebuf, sizeof(ebuf), "POST /upload HTTP/1.1\r\n" "Content-Length: %d\r\n" "Content-Type: multipart/form-data; " "boundary=%s\r\n\r\n" "%.*s", post_data_len, boundary, post_data_len, post_data)) != NULL); free(file_data), free(post_data); ASSERT(mg_read(conn, buf, sizeof(buf)) == (int) strlen(upload_ok_message)); ASSERT(memcmp(buf, upload_ok_message, strlen(upload_ok_message)) == 0); mg_close_connection(conn); mg_stop(ctx); }
static void edit_params(int argc, char** argv) { u8* tmp_dir = getenv("TMPDIR"); if (!tmp_dir) tmp_dir = "/tmp"; as_params = ck_alloc((argc + 1) * sizeof(u8*)); memcpy(as_params, argv, argc * sizeof(u8*)); as_params[0] = "as"; as_params[argc] = 0; input_file = as_params[argc - 1]; if (input_file[0] == '-') { if (input_file[1]) FATAL("Incorrect use (not called through afl-gcc?)"); else input_file = NULL; } modified_file = alloc_printf("%s/.afl-%u-%u.s", tmp_dir, getpid(), (u32)time(NULL)); as_params[argc - 1] = modified_file; }
/* dump a single line to the log for the command. * Do nothing in case we are not at debug level 3 */ void script_debug(Jim_Interp *interp, const char *name, unsigned argc, Jim_Obj * const *argv) { if (debug_level < LOG_LVL_DEBUG) return; char *dbg = alloc_printf("command - %s", name); for (unsigned i = 0; i < argc; i++) { int len; const char *w = Jim_GetString(argv[i], &len); char *t = alloc_printf("%s %s", dbg, w); free(dbg); dbg = t; } LOG_DEBUG("%s", dbg); free(dbg); }
static void detect_file_args(char** argv) { u32 i = 0; u8* cwd = getcwd(NULL, 0); if (!cwd) PFATAL("getcwd() failed"); while (argv[i]) { u8* aa_loc = strstr(argv[i], "@@"); if (aa_loc) { u8 *aa_subst, *n_arg; if (!at_file) FATAL("@@ syntax is not supported by this tool."); /* Be sure that we're always using fully-qualified paths. */ if (at_file[0] == '/') aa_subst = at_file; else aa_subst = alloc_printf("%s/%s", cwd, at_file); /* Construct a replacement argv value. */ *aa_loc = 0; n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2); argv[i] = n_arg; *aa_loc = '@'; if (at_file[0] != '/') ck_free(aa_subst); } i++; } free(cwd); /* not tracked */ }
char *get_home_dir(const char *append_path) { char *home = getenv("HOME"); if (home == NULL) { #ifdef _WIN32 home = getenv("USERPROFILE"); if (home == NULL) { char homepath[MAX_PATH]; char *drive = getenv("HOMEDRIVE"); char *path = getenv("HOMEPATH"); if (drive && path) { snprintf(homepath, MAX_PATH, "%s/%s", drive, path); home = homepath; } } #else struct passwd *pwd = getpwuid(getuid()); if (pwd) home = pwd->pw_dir; #endif } if (home == NULL) return home; char *home_path; if (append_path) home_path = alloc_printf("%s/%s", home, append_path); else home_path = alloc_printf("%s", home); return home_path; }
char *create_fmt_errno_message(const char *file, int line, int e, const char *fmt, va_list ap) { char *msg1, *msg2; va_list tmp_ap; va_copy(tmp_ap, ap); msg1 = alloc_vprintf(fmt, tmp_ap); va_end(tmp_ap); if (msg1) { if (e) msg2 = alloc_printf("fatal error (file %s, line %d) in \"%s\": error %d (%s)", file, line, msg1, e, strerror(e)); else msg2 = alloc_printf("fatal error (file %s, line %d): \"%s\"", file, line, msg1); } else { if (e) msg2 = alloc_printf("fatal error (file %s, line %d): error %d (%s)", file, line, e, strerror(e)); else msg2 = alloc_printf("fatal error (file %s, line %d)", file, line); } free(msg1); return msg2; }
static void find_binary(u8* fname) { u8* env_path = 0; struct stat st; if (strchr(fname, '/') || !(env_path = getenv("PATH"))) { target_path = ck_strdup(fname); if (stat(target_path, &st) || !S_ISREG(st.st_mode) || !(st.st_mode & 0111) || st.st_size < 4) FATAL("Program '%s' not found or not executable", fname); } else { while (env_path) { u8 *cur_elem, *delim = strchr(env_path, ':'); if (delim) { cur_elem = ck_alloc(delim - env_path + 1); memcpy(cur_elem, env_path, delim - env_path); delim++; } else cur_elem = ck_strdup(env_path); env_path = delim; if (cur_elem[0]) target_path = alloc_printf("%s/%s", cur_elem, fname); else target_path = ck_strdup(fname); ck_free(cur_elem); if (!stat(target_path, &st) && S_ISREG(st.st_mode) && (st.st_mode & 0111) && st.st_size >= 4) break; ck_free(target_path); target_path = 0; } if (!target_path) FATAL("Program '%s' not found or not executable", fname); } }
void log_impl(int prefix, int suffix, const char *fun, const char *fmt, va_list ap) { char *msg1, *msg2; struct timeval now; struct tm *tm; gettimeofday(&now, 0); tm = localtime(&now.tv_sec); msg1 = alloc_vprintf(fmt, ap); if (prefix) msg2 = alloc_printf("%04d-%02d-%02d %02d:%02d:%02d.%06ld %d %s: %s%s" , tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday , tm->tm_hour, tm->tm_min, tm->tm_sec, (long) now.tv_usec , getpid(), fun, msg1, (suffix ? "\n" : "")); else msg2 = alloc_printf("%s%s", msg1, (suffix ? "\n" : "")); /* Uncommenting the printf below will cause output to be displayed on the console until erld detaches. */ /* printf("%s", msg2); */ log_write(msg2, strlen(msg2)); free(msg2); free(msg1); }
char *read_cookie(const char *cookie_file) { char *home, *path, cookie[COOKIE_MAX_SIZE], *buf; ssize_t cookie_size; int fd; if (!cookie_file) { home = getenv("HOME"); if (!home) return 0; path = alloc_printf("%s/%s", home, DEFAULT_COOKIE_FILE_NAME); } else { path = alloc_printf("%s", cookie_file); } CHECK_F(fd = open(path, O_RDONLY), "open(\"%s\")", path); CHECK_F(cookie_size = read(fd, cookie, COOKIE_MAX_SIZE), "read(\"%s\")", path); close(fd); buf = (char *)malloc(cookie_size + 1); memcpy(buf, cookie, cookie_size); buf[cookie_size] = 0; DEBUG_V("cookie from \"%s\" is %zu bytes", path, cookie_size); free(path); return buf; }
static void setup_shm(void) { u8* shm_str; shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600); if (shm_id < 0) PFATAL("shmget() failed"); atexit(remove_shm); shm_str = alloc_printf("%d", shm_id); setenv(SHM_ENV_VAR, shm_str, 1); ck_free(shm_str); trace_bits = shmat(shm_id, NULL, 0); if (!trace_bits) PFATAL("shmat() failed"); }
static void test_mg_upload(void) { static const char *boundary = "OOO___MY_BOUNDARY___OOO"; struct mg_context *ctx; struct mg_connection *conn; char ebuf[100], buf[20], *file_data, *file2_data, *post_data; int file_len, file2_len, post_data_len; ASSERT((ctx = mg_start(OPTIONS, event_handler, NULL)) != NULL); // Upload two files ASSERT((file_data = read_file("lua_5.2.1.h", &file_len)) != NULL); ASSERT((file2_data = read_file("lsqlite3.c", &file2_len)) != NULL); post_data = NULL; post_data_len = alloc_printf(&post_data, 0, // First file "--%s\r\n" "Content-Disposition: form-data; " "name=\"file\"; " "filename=\"%s\"\r\n\r\n" "%.*s\r\n" // Second file "--%s\r\n" "Content-Disposition: form-data; " "name=\"file\"; " "filename=\"%s\"\r\n\r\n" "%.*s\r\n" // Final boundary "--%s--\r\n", boundary, "f1.txt", file_len, file_data, boundary, "f2.txt", file2_len, file2_data, boundary); ASSERT(post_data_len > 0); ASSERT((conn = mg_download("localhost", atoi(HTTPS_PORT), 1, ebuf, sizeof(ebuf), "POST /upload HTTP/1.1\r\n" "Content-Length: %d\r\n" "Content-Type: multipart/form-data; " "boundary=%s\r\n\r\n" "%.*s", post_data_len, boundary, post_data_len, post_data)) != NULL); ASSERT(mg_read(conn, buf, sizeof(buf)) == (int) strlen(upload_ok_message)); ASSERT(memcmp(buf, upload_ok_message, strlen(upload_ok_message)) == 0); mg_close_connection(conn); mg_stop(ctx); }
static void edit_params(int argc, char** argv) { u8 *tmp_dir = getenv("TMPDIR"), *afl_as = getenv("AFL_AS"); u32 i; if (!tmp_dir) tmp_dir = "/tmp"; as_params = ck_alloc((argc + 1) * sizeof(u8*)); memcpy(as_params, argv, argc * sizeof(u8*)); as_params[0] = afl_as ? afl_as : (u8*)"as"; as_params[argc] = 0; for (i = 1; i < argc; i++) { if (!strcmp(as_params[i], "--64")) use_64bit = 1; else if (!strcmp(as_params[i], "--32")) use_64bit = 0; #ifdef __APPLE__ /* The Apple case is a bit different... */ if (!strcmp(as_params[i], "-arch") && i + 1 < argc) { if (!strcmp(as_params[i + 1], "x86_64")) use_64bit = 1; else if (!strcmp(as_params[i + 1], "i386")) FATAL("Sorry, 32-bit Apple platforms are not supported."); } #endif /* __APPLE__ */ } input_file = as_params[argc - 1]; if (input_file[0] == '-') { if (input_file[1]) FATAL("Incorrect use (not called through afl-gcc?)"); else input_file = NULL; } else { /* Check if this looks like a standard invocation as a part of an attempt to compile a program, rather than using gcc on an ad-hoc .s file in a format we may not understand. This works around an issue compiling NSS. */ if (strncmp(input_file, tmp_dir, strlen(tmp_dir)) && strncmp(input_file, "/var/tmp/", 9) && strncmp(input_file, "/tmp/", 5)) pass_thru = 1; } modified_file = alloc_printf("%s/.afl-%u-%u.s", tmp_dir, getpid(), (u32)time(NULL)); as_params[argc - 1] = modified_file; }
static void add_default_dirs(void) { #ifdef _WIN32 /* Add the parent of the directory where openocd.exe resides to the * config script search path. * Directory layout: * bin\openocd.exe * lib\openocd */ { char strExePath[MAX_PATH]; GetModuleFileName(NULL, strExePath, MAX_PATH); /* Either this code will *always* work or it will SEGFAULT giving * excellent information on the culprit. */ *strrchr(strExePath, '\\') = 0; strcat(strExePath, "\\.."); add_script_search_dir(strExePath); } /* * Add support for the default (as of 20091118) layout when * using autotools and cygwin/MinGW to build native binary. * Path separator is converted to UNIX style so that MinGW is * pleased. * * bin/openocd.exe * share/openocd/scripts/interface/dummy.cfg * share/openocd/scripts/target/at91eb40a.cfg */ { char strExePath[MAX_PATH]; char *p; GetModuleFileName(NULL, strExePath, MAX_PATH); *strrchr(strExePath, '\\') = 0; strcat(strExePath, "/../share/"PACKAGE "/scripts"); for (p = strExePath; *p; p++) { if (*p == '\\') *p = '/'; } add_script_search_dir(strExePath); } #else /* * The directory containing OpenOCD-supplied scripts should be * listed last in the built-in search order, so the user can * override these scripts with site-specific customizations. */ const char *home = getenv("HOME"); if (home) { char *path; path = alloc_printf("%s/.openocd", home); if (path) { add_script_search_dir(path); free(path); } } add_script_search_dir(PKGDATADIR "/site"); add_script_search_dir(PKGDATADIR "/scripts"); #endif }
static void edit_params(int argc, char** argv) { u8 *tmp_dir = getenv("TMPDIR"), *afl_as = getenv("AFL_AS"); u32 i; #ifdef __APPLE__ u8 use_clang_as = 0; /* On MacOS X, the Xcode cctool 'as' driver is a bit stale and does not work with the code generated by newer versions of clang that are hand-built by the user. See the thread here: http://goo.gl/HBWDtn. To work around this, when using clang and running without AFL_AS specified, we will actually call 'clang -c' instead of 'as -q' to compile the assembly file. The tools aren't cmdline-compatible, but at least for now, we can seemingly get away with this by making only very minor tweaks. Thanks to Nico Weber for the idea. */ if (clang_mode && !afl_as) { use_clang_as = 1; afl_as = getenv("AFL_CC"); if (!afl_as) afl_as = getenv("AFL_CXX"); if (!afl_as) afl_as = "clang"; } #endif /* __APPLE__ */ if (!tmp_dir) tmp_dir = "/tmp"; as_params = ck_alloc((argc + 32) * sizeof(u8*)); as_params[0] = afl_as ? afl_as : (u8*)"as"; as_params[argc] = 0; for (i = 1; i < argc - 1; i++) { if (!strcmp(argv[i], "--64")) use_64bit = 1; else if (!strcmp(argv[i], "--32")) use_64bit = 0; #ifdef __APPLE__ /* The Apple case is a bit different... */ if (!strcmp(argv[i], "-arch") && i + 1 < argc) { if (!strcmp(argv[i + 1], "x86_64")) use_64bit = 1; else if (!strcmp(argv[i + 1], "i386")) FATAL("Sorry, 32-bit Apple platforms are not supported."); } /* Strip options that set the preference for a particular upstream assembler in Xcode. */ if (clang_mode && (!strcmp(argv[i], "-q") || !strcmp(argv[i], "-Q"))) continue; #endif /* __APPLE__ */ as_params[as_par_cnt++] = argv[i]; } #ifdef __APPLE__ /* When calling clang as the upstream assembler, append -c -x assembler and hope for the best. */ if (use_clang_as) { as_params[as_par_cnt++] = "-c"; as_params[as_par_cnt++] = "-x"; as_params[as_par_cnt++] = "assembler"; } #endif /* __APPLE__ */ input_file = argv[argc - 1]; if (input_file[0] == '-') { if (!strcmp(input_file + 1, "-version")) { just_version = 1; modified_file = input_file; goto wrap_things_up; } if (input_file[1]) FATAL("Incorrect use (not called through afl-gcc?)"); else input_file = NULL; } else { /* Check if this looks like a standard invocation as a part of an attempt to compile a program, rather than using gcc on an ad-hoc .s file in a format we may not understand. This works around an issue compiling NSS. */ if (strncmp(input_file, tmp_dir, strlen(tmp_dir)) && strncmp(input_file, "/var/tmp/", 9) && strncmp(input_file, "/tmp/", 5)) pass_thru = 1; } modified_file = alloc_printf("%s/.afl-%u-%u.s", tmp_dir, getpid(), (u32)time(NULL)); wrap_things_up: as_params[as_par_cnt++] = modified_file; as_params[as_par_cnt] = NULL; }
static void edit_params(u32 argc, char** argv) { u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1, bit_mode = 0; u8 *name; cc_params = ck_alloc((argc + 128) * sizeof(u8*)); name = strrchr(argv[0], '/'); if (!name) name = argv[0]; else name++; if (!strcmp(name, "afl-clang-fast++")) { u8* alt_cxx = getenv("AFL_CXX"); cc_params[0] = alt_cxx ? alt_cxx : (u8*)"clang++"; } else { u8* alt_cc = getenv("AFL_CC"); cc_params[0] = alt_cc ? alt_cc : (u8*)"clang"; } /* There are two ways to compile afl-clang-fast. In the traditional mode, we use afl-llvm-pass.so to inject instrumentation. In the experimental 'trace-pc-guard' mode, we use native LLVM instrumentation callbacks instead. The latter is a very recent addition - see: http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards */ #ifdef USE_TRACE_PC cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; cc_params[cc_par_cnt++] = "-mllvm"; cc_params[cc_par_cnt++] = "-sanitizer-coverage-block-threshold=0"; #else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path); #endif /* ^USE_TRACE_PC */ cc_params[cc_par_cnt++] = "-Qunused-arguments"; /* Detect stray -v calls from ./configure scripts. */ if (argc == 1 && !strcmp(argv[1], "-v")) maybe_linking = 0; while (--argc) { u8* cur = *(++argv); if (!strcmp(cur, "-m32")) bit_mode = 32; if (!strcmp(cur, "-m64")) bit_mode = 64; if (!strcmp(cur, "-x")) x_set = 1; if (!strcmp(cur, "-c") || !strcmp(cur, "-S") || !strcmp(cur, "-E")) maybe_linking = 0; if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) asan_set = 1; if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1; if (!strcmp(cur, "-shared")) maybe_linking = 0; if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined")) continue; cc_params[cc_par_cnt++] = cur; } if (getenv("AFL_HARDEN")) { cc_params[cc_par_cnt++] = "-fstack-protector-all"; if (!fortify_set) cc_params[cc_par_cnt++] = "-D_FORTIFY_SOURCE=2"; } if (!asan_set) { if (getenv("AFL_USE_ASAN")) { if (getenv("AFL_USE_MSAN")) FATAL("ASAN and MSAN are mutually exclusive"); if (getenv("AFL_HARDEN")) FATAL("ASAN and AFL_HARDEN are mutually exclusive"); cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; cc_params[cc_par_cnt++] = "-fsanitize=address"; } else if (getenv("AFL_USE_MSAN")) { if (getenv("AFL_USE_ASAN")) FATAL("ASAN and MSAN are mutually exclusive"); if (getenv("AFL_HARDEN")) FATAL("MSAN and AFL_HARDEN are mutually exclusive"); cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; cc_params[cc_par_cnt++] = "-fsanitize=memory"; } } #ifdef USE_TRACE_PC if (getenv("AFL_INST_RATIO")) FATAL("AFL_INST_RATIO not available at compile time with 'trace-pc'."); #endif /* USE_TRACE_PC */ if (!getenv("AFL_DONT_OPTIMIZE")) { cc_params[cc_par_cnt++] = "-g"; cc_params[cc_par_cnt++] = "-O3"; cc_params[cc_par_cnt++] = "-funroll-loops"; } if (getenv("AFL_NO_BUILTIN")) { cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp"; cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp"; cc_params[cc_par_cnt++] = "-fno-builtin-memcmp"; } cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1"; cc_params[cc_par_cnt++] = "-D__AFL_COMPILER=1"; cc_params[cc_par_cnt++] = "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1"; /* When the user tries to use persistent or deferred forkserver modes by appending a single line to the program, we want to reliably inject a signature into the binary (to be picked up by afl-fuzz) and we want to call a function from the runtime .o file. This is unnecessarily painful for three reasons: 1) We need to convince the compiler not to optimize out the signature. This is done with __attribute__((used)). 2) We need to convince the linker, when called with -Wl,--gc-sections, not to do the same. This is done by forcing an assignment to a 'volatile' pointer. 3) We need to declare __afl_persistent_loop() in the global namespace, but doing this within a method in a class is hard - :: and extern "C" are forbidden and __attribute__((alias(...))) doesn't work. Hence the __asm__ aliasing trick. */ cc_params[cc_par_cnt++] = "-D__AFL_LOOP(_A)=" "({ static volatile char *_B __attribute__((used)); " " _B = (char*)\"" PERSIST_SIG "\"; " #ifdef __APPLE__ "__attribute__((visibility(\"default\"))) " "int _L(unsigned int) __asm__(\"___afl_persistent_loop\"); " #else "__attribute__((visibility(\"default\"))) " "int _L(unsigned int) __asm__(\"__afl_persistent_loop\"); " #endif /* ^__APPLE__ */ "_L(_A); })"; cc_params[cc_par_cnt++] = "-D__AFL_INIT()=" "do { static volatile char *_A __attribute__((used)); " " _A = (char*)\"" DEFER_SIG "\"; " #ifdef __APPLE__ "__attribute__((visibility(\"default\"))) " "void _I(void) __asm__(\"___afl_manual_init\"); " #else "__attribute__((visibility(\"default\"))) " "void _I(void) __asm__(\"__afl_manual_init\"); " #endif /* ^__APPLE__ */ "_I(); } while (0)"; if (maybe_linking) { if (x_set) { cc_params[cc_par_cnt++] = "-x"; cc_params[cc_par_cnt++] = "none"; } switch (bit_mode) { case 0: cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt.o", obj_path); break; case 32: cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-32.o", obj_path); if (access(cc_params[cc_par_cnt - 1], R_OK)) FATAL("-m32 is not supported by your compiler"); break; case 64: cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-64.o", obj_path); if (access(cc_params[cc_par_cnt - 1], R_OK)) FATAL("-m64 is not supported by your compiler"); break; } } cc_params[cc_par_cnt] = NULL; }
static int add_connection(struct service *service, struct command_context *cmd_ctx) { socklen_t address_size; struct connection *c, **p; int retval; int flag = 1; c = malloc(sizeof(struct connection)); c->fd = -1; c->fd_out = -1; memset(&c->sin, 0, sizeof(c->sin)); c->cmd_ctx = copy_command_context(cmd_ctx); c->service = service; c->input_pending = 0; c->priv = NULL; c->next = NULL; if (service->type == CONNECTION_TCP) { address_size = sizeof(c->sin); c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size); c->fd_out = c->fd; /* This increases performance dramatically for e.g. GDB load which * does not have a sliding window protocol. * * Ignore errors from this fn as it probably just means less performance */ setsockopt(c->fd, /* socket affected */ IPPROTO_TCP, /* set option at TCP level */ TCP_NODELAY, /* name of option */ (char *)&flag, /* the cast is historical cruft */ sizeof(int)); /* length of option value */ LOG_INFO("accepting '%s' connection from %s", service->name, service->port); retval = service->new_connection(c); if (retval != ERROR_OK) { close_socket(c->fd); LOG_ERROR("attempted '%s' connection rejected", service->name); free(c); return retval; } } else if (service->type == CONNECTION_STDINOUT) { c->fd = service->fd; c->fd_out = fileno(stdout); #ifdef _WIN32 /* we are using stdin/out so ignore ctrl-c under windoze */ SetConsoleCtrlHandler(NULL, TRUE); #endif /* do not check for new connections again on stdin */ service->fd = -1; LOG_INFO("accepting '%s' connection from pipe", service->name); retval = service->new_connection(c); if (retval != ERROR_OK) { LOG_ERROR("attempted '%s' connection rejected", service->name); free(c); return retval; } } else if (service->type == CONNECTION_PIPE) { c->fd = service->fd; /* do not check for new connections again on stdin */ service->fd = -1; char *out_file = alloc_printf("%so", service->port); c->fd_out = open(out_file, O_WRONLY); free(out_file); if (c->fd_out == -1) { LOG_ERROR("could not open %s", service->port); exit(1); } LOG_INFO("accepting '%s' connection from pipe %s", service->name, service->port); retval = service->new_connection(c); if (retval != ERROR_OK) { LOG_ERROR("attempted '%s' connection rejected", service->name); free(c); return retval; } } /* add to the end of linked list */ for (p = &service->connections; *p; p = &(*p)->next) ; *p = c; service->max_connections--; return ERROR_OK; }
static void edit_params(u32 argc, char** argv) { u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1; u8 *name; cc_params = ck_alloc((argc + 64) * sizeof(u8*)); name = strrchr(argv[0], '/'); if (!name) name = argv[0]; else name++; if (!strcmp(name, "afl-clang-fast++")) { u8* alt_cxx = getenv("AFL_CXX"); cc_params[0] = alt_cxx ? alt_cxx : (u8*)"clang++"; } else { u8* alt_cc = getenv("AFL_CC"); cc_params[0] = alt_cc ? alt_cc : (u8*)"clang"; } cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path); cc_params[cc_par_cnt++] = "-Qunused-arguments"; while (--argc) { u8* cur = *(++argv); #if defined(__x86_64__) if (!strcmp(cur, "-m32")) FATAL("-m32 is not supported"); #endif if (!strcmp(cur, "-x")) x_set = 1; if (!strcmp(cur, "-c") || !strcmp(cur, "-S") || !strcmp(cur, "-E") || !strcmp(cur, "-v")) maybe_linking = 0; if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) asan_set = 1; if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1; cc_params[cc_par_cnt++] = cur; } if (getenv("AFL_HARDEN")) { cc_params[cc_par_cnt++] = "-fstack-protector-all"; if (!fortify_set) cc_params[cc_par_cnt++] = "-D_FORTIFY_SOURCE=2"; } if (!asan_set) { if (getenv("AFL_USE_ASAN")) { cc_params[cc_par_cnt++] = "-fsanitize=address"; if (getenv("AFL_USE_MSAN")) FATAL("ASAN and MSAN are mutually exclusive"); } else if (getenv("AFL_USE_MSAN")) { cc_params[cc_par_cnt++] = "-fsanitize=memory"; if (getenv("AFL_USE_ASAN")) FATAL("ASAN and MSAN are mutually exclusive"); } } if (!getenv("AFL_DONT_OPTIMIZE")) { cc_params[cc_par_cnt++] = "-g"; cc_params[cc_par_cnt++] = "-O3"; cc_params[cc_par_cnt++] = "-funroll-loops"; } cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1"; /* When the user tries to use persistent or deferred forkserver modes by appending a single line to the program, we want to reliably inject a signature into the binary (to be picked up by afl-fuzz) and we want to call a function from the runtime .o file. This is unnecessarily painful for three reasons: 1) We need to convince the compiler not to optimize out the signature. This is done with __attribute__((used)). 2) We need to convince the linker, when called with -Wl,--gc-sections, not to do the same. This is done by forcing an assignment to a 'volatile' pointer. 3) We need to declare __afl_persistent_loop() in the global namespace, but doing this within a method in a class is hard - :: and extern "C" are forbidden and __attribute__((alias(...))) doesn't work. Hence the __asm__ aliasing trick. */ cc_params[cc_par_cnt++] = "-D__AFL_LOOP(_A)=" "({ static volatile char *_B __attribute__((used)); " " _B = (char*)\"" PERSIST_SIG "\"; " #ifdef __APPLE__ "int _L(unsigned int) __asm__(\"___afl_persistent_loop\"); " #else "int _L(unsigned int) __asm__(\"__afl_persistent_loop\"); " #endif /* ^__APPLE__ */ "_L(_A); })"; cc_params[cc_par_cnt++] = "-D__AFL_INIT()=" "do { static volatile char *_A __attribute__((used)); " " _A = (char*)\"" DEFER_SIG "\"; " #ifdef __APPLE__ "void _I(void) __asm__(\"___afl_manual_init\"); " #else "void _I(void) __asm__(\"__afl_manual_init\"); " #endif /* ^__APPLE__ */ "_I(); } while (0)"; if (maybe_linking) { if (x_set) { cc_params[cc_par_cnt++] = "-x"; cc_params[cc_par_cnt++] = "none"; } cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt.o", obj_path); } cc_params[cc_par_cnt] = NULL; }