/src/fluent-bit/tests/internal/fuzzers/multiline_fuzzer.c
Line | Count | Source |
1 | | /* Fluent Bit |
2 | | * ========== |
3 | | * Copyright (C) 2019-2021 The Fluent Bit Authors |
4 | | * Copyright (C) 2015-2018 Treasure Data Inc. |
5 | | * |
6 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
7 | | * you may not use this file except in compliance with the License. |
8 | | * You may obtain a copy of the License at |
9 | | * |
10 | | * http://www.apache.org/licenses/LICENSE-2.0 |
11 | | * |
12 | | * Unless required by applicable law or agreed to in writing, software |
13 | | * distributed under the License is distributed on an "AS IS" BASIS, |
14 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 | | * See the License for the specific language governing permissions and |
16 | | * limitations under the License. |
17 | | */ |
18 | | #include <stdint.h> |
19 | | #include <stdlib.h> |
20 | | |
21 | | #include <fluent-bit/flb_info.h> |
22 | | #include <fluent-bit/flb_mem.h> |
23 | | #include <fluent-bit/flb_pack.h> |
24 | | #include <fluent-bit/flb_parser.h> |
25 | | #include <fluent-bit/multiline/flb_ml.h> |
26 | | #include <fluent-bit/multiline/flb_ml_parser.h> |
27 | | #include <fluent-bit/multiline/flb_ml_rule.h> |
28 | | |
29 | | #include "flb_fuzz_header.h" |
30 | | |
31 | | static int flush_callback(struct flb_ml_parser *parser, |
32 | | struct flb_ml_stream *mst, void *data, char *buf_data, |
33 | 146k | size_t buf_size) { |
34 | 146k | return 0; |
35 | 146k | } |
36 | | |
37 | | struct record_check { |
38 | | char *buf; |
39 | | }; |
40 | | |
41 | | struct expected_result { |
42 | | int current_record; |
43 | | char *key; |
44 | | struct record_check *out_records; |
45 | | }; |
46 | | |
47 | | char *random_strings[4]; |
48 | | |
49 | 2.66k | void test_multiline_parser(msgpack_object *root2, int rand_val) { |
50 | 2.66k | struct expected_result res = {0}; |
51 | 2.66k | struct flb_config *config = NULL; |
52 | | |
53 | 2.66k | config = flb_config_init(); |
54 | | |
55 | 2.66k | struct flb_ml *ml = NULL; |
56 | 2.66k | ml = flb_ml_create(config, "fuzz-test"); |
57 | | |
58 | 2.66k | if (ml != NULL) { |
59 | 2.66k | uint64_t stream_ids[5]; |
60 | | |
61 | 2.66k | flb_ml_parser_instance_create(ml, "docker"); |
62 | 2.66k | flb_ml_parser_instance_create(ml, "python"); |
63 | 2.66k | flb_ml_parser_instance_create(ml, "go"); |
64 | 2.66k | flb_ml_parser_instance_create(ml, "cri"); |
65 | 2.66k | struct flb_ml_parser_ins *mlp_i = |
66 | 2.66k | flb_ml_parser_instance_create(ml, "java"); |
67 | 2.66k | flb_ml_parser_instance_set(mlp_i, "key_content", "log"); |
68 | | |
69 | 2.66k | if (rand_val & 0x01) { |
70 | 1.69k | flb_ml_stream_create(ml, "java", -1, flush_callback, (void *)&res, |
71 | 1.69k | &(stream_ids[0])); |
72 | 1.69k | } |
73 | 2.66k | if (rand_val >> 1 & 0x01) { |
74 | 1.44k | flb_ml_stream_create(ml, "python", -1, flush_callback, (void *)&res, |
75 | 1.44k | &(stream_ids[1])); |
76 | 1.44k | } |
77 | 2.66k | if (rand_val >> 2 & 0x01) { |
78 | 1.65k | flb_ml_stream_create(ml, "go", -1, flush_callback, (void *)&res, |
79 | 1.65k | &(stream_ids[2])); |
80 | 1.65k | } |
81 | 2.66k | if (rand_val >> 3 & 0x01) { |
82 | 1.65k | flb_ml_stream_create(ml, "docker", -1, flush_callback, (void *)&res, |
83 | 1.65k | &(stream_ids[3])); |
84 | 1.65k | } |
85 | 2.66k | if (rand_val >> 4 & 0x01) { |
86 | 1.31k | flb_ml_stream_create(ml, "cri", -1, flush_callback, (void *)&res, |
87 | 1.31k | &(stream_ids[4])); |
88 | 1.31k | } |
89 | | |
90 | | /* Target with msgpack object */ |
91 | 2.66k | if (root2 != NULL) { |
92 | 1.54k | struct flb_time tm; |
93 | 1.54k | flb_time_get(&tm); |
94 | 7.72k | for (int i = 0; i < 4; i++) { |
95 | 6.17k | flb_ml_append_object(ml, stream_ids[i], &tm, root2); |
96 | 6.17k | } |
97 | 1.54k | } |
98 | | |
99 | | /* Target with raw text */ |
100 | 2.66k | struct flb_time tm2; |
101 | 2.66k | flb_time_get(&tm2); |
102 | 13.3k | for (int i = 0; i < 4; i++) { |
103 | 64.0k | for (int j = 0; j < 5; j++) { |
104 | 53.3k | if (random_strings[i] != NULL && stream_ids[j] != NULL) { |
105 | | /* stream_ids index by j, random_strings index by i */ |
106 | 38.5k | flb_ml_append(ml, stream_ids[j], FLB_ML_TYPE_TEXT, &tm2, |
107 | 38.5k | random_strings[i], strlen(random_strings[i])); |
108 | 38.5k | flb_ml_append(ml, stream_ids[j], |
109 | 38.5k | flb_ml_type_lookup("endswith"), &tm2, |
110 | 38.5k | random_strings[i], strlen(random_strings[i])); |
111 | 38.5k | flb_ml_append(ml, stream_ids[j], |
112 | 38.5k | flb_ml_type_lookup("regex"), &tm2, |
113 | 38.5k | random_strings[i], strlen(random_strings[i])); |
114 | 38.5k | flb_ml_append(ml, stream_ids[j], flb_ml_type_lookup("eq"), |
115 | 38.5k | &tm2, random_strings[i], |
116 | 38.5k | strlen(random_strings[i])); |
117 | 38.5k | flb_ml_append(ml, stream_ids[j], |
118 | 38.5k | flb_ml_type_lookup("equal"), &tm2, |
119 | 38.5k | random_strings[i], strlen(random_strings[i])); |
120 | 38.5k | } |
121 | 53.3k | } |
122 | 10.6k | } |
123 | 2.66k | } |
124 | | |
125 | 2.66k | flb_ml_flush_pending_now(ml); |
126 | | |
127 | 2.66k | if (ml) { |
128 | 2.66k | flb_ml_destroy(ml); |
129 | 2.66k | } |
130 | | |
131 | 2.66k | flb_config_exit(config); |
132 | 2.66k | } |
133 | | |
134 | 2.86k | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
135 | 2.86k | TIMEOUT_GUARD |
136 | 2.85k | flb_malloc_p = 0; |
137 | | /* Ensure there's enough data */ |
138 | 2.85k | if (size < 250) { |
139 | 22 | return 0; |
140 | 22 | } |
141 | | |
142 | 2.83k | int rand_val = *(int *)data; |
143 | 2.83k | data += 4; |
144 | 2.83k | size -= 4; |
145 | 14.1k | for (int i = 0; i < 4; i++) { |
146 | 11.3k | random_strings[i] = NULL; |
147 | 11.3k | } |
148 | | |
149 | 2.83k | random_strings[0] = get_null_terminated(40, &data, &size); |
150 | 2.83k | random_strings[1] = get_null_terminated(40, &data, &size); |
151 | 2.83k | random_strings[2] = get_null_terminated(40, &data, &size); |
152 | 2.83k | random_strings[3] = get_null_terminated(40, &data, &size); |
153 | | |
154 | 2.83k | char *out_buf = NULL; |
155 | 2.83k | size_t out_size; |
156 | 2.83k | int root_type; |
157 | 2.83k | int ret = |
158 | 2.83k | flb_pack_json((char *)data, size, &out_buf, &out_size, &root_type); |
159 | 2.83k | if (ret == 0) { |
160 | 1.71k | size_t off = 0; |
161 | 1.71k | msgpack_unpacked result; |
162 | 1.71k | msgpack_unpacked_init(&result); |
163 | 1.71k | int ret2 = msgpack_unpack_next(&result, out_buf, out_size, &off); |
164 | 1.71k | if (ret2 == MSGPACK_UNPACK_SUCCESS) { |
165 | 1.54k | msgpack_object root = result.data; |
166 | | |
167 | | /* Pass fuzz data into the multiline parser code */ |
168 | 1.54k | test_multiline_parser(&root, rand_val); |
169 | 1.54k | } |
170 | 1.71k | msgpack_unpacked_destroy(&result); |
171 | 1.71k | free(out_buf); |
172 | 1.71k | } else { |
173 | 1.12k | test_multiline_parser(NULL, rand_val); |
174 | 1.12k | } |
175 | | |
176 | 14.1k | for (int i = 0; i < 4; i++) { |
177 | 11.3k | if (random_strings[i] != NULL) { |
178 | 11.3k | free(random_strings[i]); |
179 | 11.3k | } |
180 | 11.3k | } |
181 | 2.83k | return 0; |
182 | 2.85k | } |