summaryrefslogtreecommitdiffstats
path: root/src/fluent-bit/tests/internal/fuzzers/multiline_fuzzer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fluent-bit/tests/internal/fuzzers/multiline_fuzzer.c')
-rw-r--r--src/fluent-bit/tests/internal/fuzzers/multiline_fuzzer.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/src/fluent-bit/tests/internal/fuzzers/multiline_fuzzer.c b/src/fluent-bit/tests/internal/fuzzers/multiline_fuzzer.c
new file mode 100644
index 000000000..bc03e2462
--- /dev/null
+++ b/src/fluent-bit/tests/internal/fuzzers/multiline_fuzzer.c
@@ -0,0 +1,180 @@
+/* Fluent Bit
+ * ==========
+ * Copyright (C) 2019-2021 The Fluent Bit Authors
+ * Copyright (C) 2015-2018 Treasure Data Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <fluent-bit/flb_info.h>
+#include <fluent-bit/flb_mem.h>
+#include <fluent-bit/flb_pack.h>
+#include <fluent-bit/flb_parser.h>
+#include <fluent-bit/multiline/flb_ml.h>
+#include <fluent-bit/multiline/flb_ml_parser.h>
+#include <fluent-bit/multiline/flb_ml_rule.h>
+
+#include "flb_fuzz_header.h"
+
+static int flush_callback(struct flb_ml_parser *parser,
+ struct flb_ml_stream *mst, void *data, char *buf_data,
+ size_t buf_size) {
+ return 0;
+}
+
+struct record_check {
+ char *buf;
+};
+
+struct expected_result {
+ int current_record;
+ char *key;
+ struct record_check *out_records;
+};
+
+char *random_strings[4];
+
+void test_multiline_parser(msgpack_object *root2, int rand_val) {
+ struct expected_result res = {0};
+ struct flb_config *config = NULL;
+
+ config = flb_config_init();
+
+ struct flb_ml *ml = NULL;
+ ml = flb_ml_create(config, "fuzz-test");
+
+ if (ml != NULL) {
+ uint64_t stream_ids[5];
+
+ flb_ml_parser_instance_create(ml, "docker");
+ flb_ml_parser_instance_create(ml, "python");
+ flb_ml_parser_instance_create(ml, "go");
+ flb_ml_parser_instance_create(ml, "cri");
+ struct flb_ml_parser_ins *mlp_i =
+ flb_ml_parser_instance_create(ml, "java");
+ flb_ml_parser_instance_set(mlp_i, "key_content", "log");
+
+ if (rand_val & 0x01) {
+ flb_ml_stream_create(ml, "java", -1, flush_callback, (void *)&res,
+ &(stream_ids[0]));
+ }
+ if (rand_val >> 1 & 0x01) {
+ flb_ml_stream_create(ml, "python", -1, flush_callback, (void *)&res,
+ &(stream_ids[1]));
+ }
+ if (rand_val >> 2 & 0x01) {
+ flb_ml_stream_create(ml, "go", -1, flush_callback, (void *)&res,
+ &(stream_ids[2]));
+ }
+ if (rand_val >> 3 & 0x01) {
+ flb_ml_stream_create(ml, "docker", -1, flush_callback, (void *)&res,
+ &(stream_ids[3]));
+ }
+ if (rand_val >> 4 & 0x01) {
+ flb_ml_stream_create(ml, "cri", -1, flush_callback, (void *)&res,
+ &(stream_ids[4]));
+ }
+
+ /* Target with msgpack object */
+ if (root2 != NULL) {
+ struct flb_time tm;
+ flb_time_get(&tm);
+ for (int i = 0; i < 4; i++) {
+ flb_ml_append_object(ml, stream_ids[i], &tm, NULL, root2);
+ }
+ }
+
+ /* Target with raw text */
+ struct flb_time tm2;
+ flb_time_get(&tm2);
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 5; j++) {
+ if (random_strings[i] != NULL && stream_ids[j] != NULL) {
+ /* stream_ids index by j, random_strings index by i */
+ flb_ml_append_text(ml, stream_ids[j], &tm2,
+ random_strings[i], strlen(random_strings[i]));
+ flb_ml_append_text(ml, stream_ids[j], &tm2,
+ random_strings[i], strlen(random_strings[i]));
+ flb_ml_append_text(ml, stream_ids[j], &tm2,
+ random_strings[i], strlen(random_strings[i]));
+ flb_ml_append_text(ml, stream_ids[j], &tm2,
+ random_strings[i],strlen(random_strings[i]));
+ flb_ml_append_text(ml, stream_ids[j], &tm2,
+ random_strings[i], strlen(random_strings[i]));
+ }
+ }
+ }
+ }
+
+ flb_ml_flush_pending_now(ml);
+
+ if (ml) {
+ flb_ml_destroy(ml);
+ }
+
+ flb_config_exit(config);
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ TIMEOUT_GUARD
+ /* Set fuzzer-malloc chance of failure */
+ flb_malloc_mod = 25000;
+ flb_malloc_p = 0;
+ /* Ensure there's enough data */
+ if (size < 250) {
+ return 0;
+ }
+
+ int rand_val = *(int *)data;
+ data += 4;
+ size -= 4;
+ for (int i = 0; i < 4; i++) {
+ random_strings[i] = NULL;
+ }
+
+ random_strings[0] = get_null_terminated(40, &data, &size);
+ random_strings[1] = get_null_terminated(40, &data, &size);
+ random_strings[2] = get_null_terminated(40, &data, &size);
+ random_strings[3] = get_null_terminated(40, &data, &size);
+
+ char *out_buf = NULL;
+ size_t out_size;
+ int root_type;
+ int ret =
+ flb_pack_json((char *)data, size, &out_buf, &out_size, &root_type, NULL);
+ if (ret == 0) {
+ size_t off = 0;
+ msgpack_unpacked result;
+ msgpack_unpacked_init(&result);
+ int ret2 = msgpack_unpack_next(&result, out_buf, out_size, &off);
+ if (ret2 == MSGPACK_UNPACK_SUCCESS) {
+ msgpack_object root = result.data;
+
+ /* Pass fuzz data into the multiline parser code */
+ test_multiline_parser(&root, rand_val);
+ }
+ msgpack_unpacked_destroy(&result);
+ free(out_buf);
+ } else {
+ test_multiline_parser(NULL, rand_val);
+ }
+
+ for (int i = 0; i < 4; i++) {
+ if (random_strings[i] != NULL) {
+ free(random_strings[i]);
+ }
+ }
+ return 0;
+}