|
| 1 | +#include <fluent-bit.h> |
| 2 | +#include <pthread.h> |
| 3 | +#include <stdlib.h> |
| 4 | +#include <unistd.h> |
| 5 | +#include <stdint.h> |
| 6 | +#include <sys/stat.h> |
| 7 | +#include <fluent-bit/flb_input_chunk.h> |
| 8 | +#include <fluent-bit/flb_storage.h> |
| 9 | +#include <fluent-bit/flb_router.h> |
| 10 | +#include <fluent-bit/flb_time.h> |
| 11 | + |
| 12 | +#include "chunkio/chunkio.h" |
| 13 | +#include "flb_fuzz_header.h" |
| 14 | + |
| 15 | + |
| 16 | +const char *input_chunk_property_keywords[] = { |
| 17 | + "log_suppress_interval", |
| 18 | + "routable", |
| 19 | + "alias", |
| 20 | + "mem_buf_limit", |
| 21 | + "listen", |
| 22 | + "log_level", |
| 23 | + "host", |
| 24 | + "port", |
| 25 | + "ipv6", |
| 26 | + "net.", |
| 27 | + "tls", |
| 28 | + "tls.verify", |
| 29 | + "tls.debug", |
| 30 | + "tls.ca_path", |
| 31 | + "tls.key_file", |
| 32 | + "tls.vhost", |
| 33 | + "tls.ca_file", |
| 34 | + "tls.crt_file", |
| 35 | + "tls.key_passwd", |
| 36 | + "threaded", |
| 37 | + "storage.type", |
| 38 | +}; |
| 39 | + |
| 40 | +int LLVMFuzzerTestOneInput(const uint8_t *data3, size_t size3) |
| 41 | +{ |
| 42 | + int i; |
| 43 | + int ret; |
| 44 | + int in_ffd; |
| 45 | + int out_ffd; |
| 46 | + |
| 47 | + flb_ctx_t *ctx; |
| 48 | + size_t total_bytes; |
| 49 | + struct flb_input_instance *i_ins; |
| 50 | + struct mk_list *tmp; |
| 51 | + struct mk_list *head; |
| 52 | + struct flb_input_chunk *ic; |
| 53 | + struct flb_task *task; |
| 54 | + |
| 55 | + if (size3 < 60) { |
| 56 | + return 0; |
| 57 | + } |
| 58 | + /* Set fuzzer-malloc chance of failure */ |
| 59 | + flb_malloc_p = 0; |
| 60 | + flb_malloc_mod = 25000; |
| 61 | + char *input_buffer1 = get_null_terminated(30, &data3, &size3); |
| 62 | + if (input_buffer1 == NULL) { |
| 63 | + return 0; |
| 64 | + } |
| 65 | + size_t input_buffer1_len = strlen(input_buffer1); |
| 66 | + |
| 67 | + char *input_buffer2 = get_null_terminated(10, &data3, &size3); |
| 68 | + if (input_buffer2 == NULL) { |
| 69 | + return 0; |
| 70 | + } |
| 71 | + size_t input_buffer_len2 = strlen(input_buffer2); |
| 72 | + |
| 73 | + char *input_buffer3 = get_null_terminated(10, &data3, &size3); |
| 74 | + if (input_buffer3 == NULL) { |
| 75 | + return 0; |
| 76 | + } |
| 77 | + size_t input_buffer_len3 = strlen(input_buffer3); |
| 78 | + /* Create context, flush every second (some checks omitted here) */ |
| 79 | + ctx = flb_create(); |
| 80 | + |
| 81 | + /* create chunks in /tmp folder */ |
| 82 | + ret = flb_service_set(ctx, |
| 83 | + "flush", "2", "grace", "1", |
| 84 | + "storage.path", "/tmp/input-chunk-test/", |
| 85 | + "Log_Level", "error", |
| 86 | + NULL); |
| 87 | + if (ret != 0) { |
| 88 | + flb_free(input_buffer1); |
| 89 | + flb_free(input_buffer2); |
| 90 | + flb_free(input_buffer3); |
| 91 | + return 0; |
| 92 | + } |
| 93 | + |
| 94 | + /* Lib input mode */ |
| 95 | + in_ffd = flb_input(ctx, (char *) "lib", NULL); |
| 96 | + ret = flb_input_set(ctx, in_ffd, |
| 97 | + "tag", "test", |
| 98 | + "storage.type", "filesystem", |
| 99 | + NULL); |
| 100 | + if (ret != 0) { |
| 101 | + flb_free(input_buffer1); |
| 102 | + flb_free(input_buffer2); |
| 103 | + flb_free(input_buffer3); |
| 104 | + return 0; |
| 105 | + } |
| 106 | + |
| 107 | + /* an invalid output destination */ |
| 108 | + out_ffd = flb_output(ctx, (char *) "http", NULL); |
| 109 | + flb_output_set(ctx, out_ffd, |
| 110 | + "match", "test", |
| 111 | + "Host", "127.0.0.1", |
| 112 | + "Port", "1", |
| 113 | + "storage.total_limit_size", "1K", |
| 114 | + NULL); |
| 115 | + |
| 116 | + /* Start */ |
| 117 | + ret = flb_start(ctx); |
| 118 | + if (ret != 0) { |
| 119 | + flb_free(input_buffer1); |
| 120 | + flb_free(input_buffer2); |
| 121 | + flb_free(input_buffer3); |
| 122 | + return 0; |
| 123 | + } |
| 124 | + |
| 125 | + i_ins = mk_list_entry_first(&ctx->config->inputs, |
| 126 | + struct flb_input_instance, |
| 127 | + _head); |
| 128 | + |
| 129 | + /* main fuzzing logic */ |
| 130 | + flb_input_set_property(i_ins, input_buffer2, input_buffer3); |
| 131 | + for (int i = 0; i < sizeof(input_chunk_property_keywords)/sizeof(char*); i++) { |
| 132 | + flb_input_set_property(i_ins, |
| 133 | + input_chunk_property_keywords[i], |
| 134 | + input_buffer3); |
| 135 | + } |
| 136 | + |
| 137 | + /* Ingest fuzz data sample */ |
| 138 | + for (i = 0; i < 2; ++i) { |
| 139 | + flb_lib_push(ctx, in_ffd, (char *) input_buffer1, input_buffer1_len); |
| 140 | + sleep(1); |
| 141 | + total_bytes = flb_input_chunk_total_size(i_ins); |
| 142 | + ret = total_bytes > 1000 ? -1 : 0; |
| 143 | + } |
| 144 | + |
| 145 | + /* FORCE clean up test tasks */ |
| 146 | + mk_list_foreach_safe(head, tmp, &i_ins->tasks) { |
| 147 | + task = mk_list_entry(head, struct flb_task, _head); |
| 148 | + flb_info("[task] cleanup test task"); |
| 149 | + flb_task_destroy(task, FLB_TRUE); |
| 150 | + } |
| 151 | + |
| 152 | + /* clean up test chunks */ |
| 153 | + mk_list_foreach_safe(head, tmp, &i_ins->chunks) { |
| 154 | + ic = mk_list_entry(head, struct flb_input_chunk, _head); |
| 155 | + flb_input_chunk_destroy(ic, FLB_TRUE); |
| 156 | + } |
| 157 | + flb_free(input_buffer1); |
| 158 | + flb_free(input_buffer2); |
| 159 | + flb_free(input_buffer3); |
| 160 | + |
| 161 | + flb_time_msleep(200); |
| 162 | + flb_stop(ctx); |
| 163 | + flb_destroy(ctx); |
| 164 | +} |
0 commit comments