Coverage Report

Created: 2026-06-07 07:09

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