Coverage Report

Created: 2023-01-10 07:10

/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
}