/src/fluent-bit/tests/internal/fuzzers/input_fuzzer.c
Line | Count | Source |
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 | 115 | { |
42 | 115 | int i; |
43 | 115 | int ret; |
44 | 115 | int in_ffd; |
45 | 115 | int out_ffd; |
46 | | |
47 | 115 | flb_ctx_t *ctx; |
48 | 115 | size_t total_bytes; |
49 | 115 | struct flb_input_instance *i_ins; |
50 | 115 | struct mk_list *tmp; |
51 | 115 | struct mk_list *head; |
52 | 115 | struct flb_input_chunk *ic; |
53 | 115 | struct flb_task *task; |
54 | | |
55 | 115 | if (size3 < 60) { |
56 | 0 | return 0; |
57 | 0 | } |
58 | | /* Set fuzzer-malloc chance of failure */ |
59 | 115 | flb_malloc_p = 0; |
60 | 115 | flb_malloc_mod = 25000; |
61 | 115 | char *input_buffer1 = get_null_terminated(30, &data3, &size3); |
62 | 115 | if (input_buffer1 == NULL) { |
63 | 0 | return 0; |
64 | 0 | } |
65 | 115 | size_t input_buffer1_len = strlen(input_buffer1); |
66 | | |
67 | 115 | char *input_buffer2 = get_null_terminated(10, &data3, &size3); |
68 | 115 | if (input_buffer2 == NULL) { |
69 | 0 | return 0; |
70 | 0 | } |
71 | 115 | size_t input_buffer_len2 = strlen(input_buffer2); |
72 | | |
73 | 115 | char *input_buffer3 = get_null_terminated(10, &data3, &size3); |
74 | 115 | if (input_buffer3 == NULL) { |
75 | 0 | return 0; |
76 | 0 | } |
77 | 115 | size_t input_buffer_len3 = strlen(input_buffer3); |
78 | | /* Create context, flush every second (some checks omitted here) */ |
79 | 115 | ctx = flb_create(); |
80 | | |
81 | | /* create chunks in /tmp folder */ |
82 | 115 | ret = flb_service_set(ctx, |
83 | 115 | "flush", "2", "grace", "1", |
84 | 115 | "storage.path", "/tmp/input-chunk-test/", |
85 | 115 | "Log_Level", "error", |
86 | 115 | NULL); |
87 | 115 | if (ret != 0) { |
88 | 0 | flb_free(input_buffer1); |
89 | 0 | flb_free(input_buffer2); |
90 | 0 | flb_free(input_buffer3); |
91 | 0 | return 0; |
92 | 0 | } |
93 | | |
94 | | /* Lib input mode */ |
95 | 115 | in_ffd = flb_input(ctx, (char *) "lib", NULL); |
96 | 115 | ret = flb_input_set(ctx, in_ffd, |
97 | 115 | "tag", "test", |
98 | 115 | "storage.type", "filesystem", |
99 | 115 | NULL); |
100 | 115 | if (ret != 0) { |
101 | 0 | flb_free(input_buffer1); |
102 | 0 | flb_free(input_buffer2); |
103 | 0 | flb_free(input_buffer3); |
104 | 0 | return 0; |
105 | 0 | } |
106 | | |
107 | | /* an invalid output destination */ |
108 | 115 | out_ffd = flb_output(ctx, (char *) "http", NULL); |
109 | 115 | flb_output_set(ctx, out_ffd, |
110 | 115 | "match", "test", |
111 | 115 | "Host", "127.0.0.1", |
112 | 115 | "Port", "1", |
113 | 115 | "storage.total_limit_size", "1K", |
114 | 115 | NULL); |
115 | | |
116 | | /* Start */ |
117 | 115 | ret = flb_start(ctx); |
118 | 115 | if (ret != 0) { |
119 | 0 | flb_free(input_buffer1); |
120 | 0 | flb_free(input_buffer2); |
121 | 0 | flb_free(input_buffer3); |
122 | 0 | return 0; |
123 | 0 | } |
124 | | |
125 | 115 | i_ins = mk_list_entry_first(&ctx->config->inputs, |
126 | 115 | struct flb_input_instance, |
127 | 115 | _head); |
128 | | |
129 | | /* main fuzzing logic */ |
130 | 115 | flb_input_set_property(i_ins, input_buffer2, input_buffer3); |
131 | 2.53k | for (int i = 0; i < sizeof(input_chunk_property_keywords)/sizeof(char*); i++) { |
132 | 2.41k | flb_input_set_property(i_ins, |
133 | 2.41k | input_chunk_property_keywords[i], |
134 | 2.41k | input_buffer3); |
135 | 2.41k | } |
136 | | |
137 | | /* Ingest fuzz data sample */ |
138 | 345 | for (i = 0; i < 2; ++i) { |
139 | 230 | flb_lib_push(ctx, in_ffd, (char *) input_buffer1, input_buffer1_len); |
140 | 230 | sleep(1); |
141 | 230 | total_bytes = flb_input_chunk_total_size(i_ins); |
142 | 230 | ret = total_bytes > 1000 ? -1 : 0; |
143 | 230 | } |
144 | | |
145 | | /* FORCE clean up test tasks */ |
146 | 115 | mk_list_foreach_safe(head, tmp, &i_ins->tasks) { |
147 | 20 | task = mk_list_entry(head, struct flb_task, _head); |
148 | 20 | flb_info("[task] cleanup test task"); |
149 | 20 | flb_task_destroy(task, FLB_TRUE); |
150 | 20 | } |
151 | | |
152 | | /* clean up test chunks */ |
153 | 115 | mk_list_foreach_safe(head, tmp, &i_ins->chunks) { |
154 | 0 | ic = mk_list_entry(head, struct flb_input_chunk, _head); |
155 | 0 | flb_input_chunk_destroy(ic, FLB_TRUE); |
156 | 0 | } |
157 | 115 | flb_free(input_buffer1); |
158 | 115 | flb_free(input_buffer2); |
159 | 115 | flb_free(input_buffer3); |
160 | | |
161 | 115 | flb_time_msleep(200); |
162 | 115 | flb_stop(ctx); |
163 | 115 | flb_destroy(ctx); |
164 | 115 | } |