static int tfw_bmb_worker(void *data) { int tn = (int)(long)data; TfwBmbTask *task = &bmb_task[tn]; int attempt, send, k, i; unsigned long time_max; fuzz_init(&task->ctx, true); for (k = 0; k < niters; k++) { task->conn_attempt = 0; atomic_set(&task->conn_compl, 0); atomic_set(&task->conn_error, 0); atomic_set(&task->conn_rd_tail, 0); init_waitqueue_head(&task->conn_wq); for (i = 0; i < nconns; i++) tfw_bmb_connect(tn, i); set_freezable(); time_max = jiffies + 60 * HZ; attempt = task->conn_attempt; do { #define COND() (atomic_read(&task->conn_compl) > 0 || \ atomic_read(&task->conn_error) == attempt) wait_event_freezable_timeout(task->conn_wq, COND(), HZ); #undef COND if (atomic_read(&task->conn_compl) > 0) break; if (atomic_read(&task->conn_error) == attempt) goto release_sockets; if (jiffies > time_max) { TFW_ERR("worker exceeded maximum wait time\n"); goto release_sockets; } } while (!kthread_should_stop()); for (send = 0; send < nconns * nmessages; ) { int tail = atomic_read(&task->conn_rd_tail); for (i = 0; i < tail; i++){ tfw_bmb_msg_send(tn, task->conn_rd[i]); send++; } } release_sockets: atomic_add(attempt, &bmb_conn_attempt); atomic_add(atomic_read(&task->conn_compl), &bmb_conn_compl); atomic_add(atomic_read(&task->conn_error), &bmb_conn_error); tfw_bmb_release_sockets(tn); } task->task_struct = NULL; atomic_dec(&bmb_threads); wake_up(&bmb_task_wq); return 0; }
int main(int argc, char **argv) { size_t size; global_init(); /* Disable logging by default to speed up fuzzing. */ int loglevel = LOG_ERR; for (int i = 1; i < argc; ++i) { if (!strcmp(argv[i], "--warn")) { loglevel = LOG_WARN; } else if (!strcmp(argv[i], "--notice")) { loglevel = LOG_NOTICE; } else if (!strcmp(argv[i], "--info")) { loglevel = LOG_INFO; } else if (!strcmp(argv[i], "--debug")) { loglevel = LOG_DEBUG; } } { log_severity_list_t s; memset(&s, 0, sizeof(s)); set_log_severity_config(loglevel, LOG_ERR, &s); /* ALWAYS log bug warnings. */ s.masks[LOG_WARN-LOG_ERR] |= LD_BUG; add_stream_log(&s, "", fileno(stdout)); } if (fuzz_init() < 0) abort(); #ifdef __AFL_HAVE_MANUAL_CONTROL /* Tell AFL to pause and fork here - ignored if not using AFL */ __AFL_INIT(); #endif #define MAX_FUZZ_SIZE (128*1024) char *input = read_file_to_str_until_eof(0, MAX_FUZZ_SIZE, &size); tor_assert(input); char *raw = tor_memdup(input, size); /* Because input is nul-terminated */ tor_free(input); fuzz_main((const uint8_t*)raw, size); tor_free(raw); if (fuzz_cleanup() < 0) abort(); tor_free(mock_options); UNMOCK(get_options); return 0; }
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { static int initialized = 0; if (!initialized) { global_init(); if (fuzz_init() < 0) abort(); initialized = 1; } return fuzz_main(Data, Size); }
static void tfw_bmb_msg_send(int tn, int cn) { TfwBmbTask *task = &bmb_task[tn]; int fz_tries = 0, r; TfwStr msg; TfwHttpMsg req; TfwMsgIter it; BUG_ON(!task->conn[cn].sk); do { if (++fz_tries > 10) { TFW_ERR("Too many fuzzer tries to generate request\n"); return; } r = fuzz_gen(&task->ctx, task->buf, task->buf + BUF_SIZE, 0, 1, FUZZ_REQ); if (r < 0) { TFW_ERR("Cannot generate HTTP request, r=%d\n", r); return; } if (r == FUZZ_END) fuzz_init(&task->ctx, true); } while (r != FUZZ_VALID); msg.ptr = task->buf; msg.skb = NULL; msg.len = strlen(msg.ptr); msg.flags = 0; if (!tfw_http_msg_create(&req, &it, Conn_Clnt, msg.len)) { TFW_WARN("Cannot create HTTP request.\n"); return; } if (verbose) TFW_LOG("Send request:\n" "------------------------------\n" "%s\n" "------------------------------\n", task->buf); tfw_http_msg_write(&it, &req, &msg); ss_send(task->conn[cn].sk, &req.msg.skb_list, true); atomic_inc(&bmb_request_send); }