Coverage Report

Created: 2026-08-09 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fluent-bit/tests/internal/fuzzers/log_cache_fuzzer.c
Line
Count
Source
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*  Fluent Bit
4
 *  ==========
5
 *  Copyright (C) 2015-2026 The Fluent Bit Authors
6
 *
7
 *  Licensed under the Apache License, Version 2.0 (the "License");
8
 *  you may not use this file except in compliance with the License.
9
 *  You may obtain a copy of the License at
10
 *
11
 *      http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 *  Unless required by applicable law or agreed to in writing, software
14
 *  distributed under the License is distributed on an "AS IS" BASIS,
15
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 *  See the License for the specific language governing permissions and
17
 *  limitations under the License.
18
 */
19
20
#include <limits.h>
21
#include <stdint.h>
22
#include <stdlib.h>
23
#include <string.h>
24
25
#include <fluent-bit/flb_log.h>
26
#include <fluent-bit/flb_mem.h>
27
28
281
#define MAX_CACHE_ENTRIES 8
29
30
#ifdef FLB_HAVE_TESTS_OSSFUZZ
31
static void silence_expected_allocation_errors(void)
32
281
{
33
281
    static struct flb_log log;
34
281
    static struct flb_worker worker;
35
36
281
    log.level = FLB_LOG_OFF;
37
281
    worker.log_ctx = &log;
38
39
281
    FLB_TLS_INIT(flb_worker_ctx);
40
281
    FLB_TLS_SET(flb_worker_ctx, &worker);
41
281
}
42
43
static void reset_fuzz_allocator(void)
44
3.53k
{
45
3.53k
    flb_malloc_p = 0;
46
3.53k
    flb_malloc_mod = INT_MAX;
47
3.53k
}
48
49
static void exercise_cache_create_allocation_failures(int timeout, int entries)
50
281
{
51
281
    int i;
52
281
    int allocation_count;
53
281
    struct flb_log_cache *cache;
54
55
    /* The cache and each entry and its buffer require one allocation each. */
56
281
    allocation_count = 1 + (entries * 2);
57
58
3.25k
    for (i = 1; i <= allocation_count; i++) {
59
2.97k
        flb_malloc_mod = allocation_count + 1;
60
2.97k
        flb_malloc_p = flb_malloc_mod - i;
61
62
2.97k
        cache = flb_log_cache_create(timeout, entries);
63
64
2.97k
        reset_fuzz_allocator();
65
2.97k
        if (cache != NULL) {
66
0
            flb_log_cache_destroy(cache);
67
0
            abort();
68
0
        }
69
2.97k
    }
70
281
}
71
72
static void exercise_message_allocation_failure(struct flb_log_cache *cache,
73
                                                uint8_t value)
74
281
{
75
281
    char message[FLB_LOG_CACHE_TEXT_BUF_SIZE + 1];
76
281
    struct flb_log_cache_entry *entry;
77
78
281
    memset(message, value, sizeof(message));
79
80
    /* Force the next allocation, used to grow the message buffer, to fail. */
81
281
    flb_malloc_mod = 2;
82
281
    flb_malloc_p = 1;
83
281
    flb_log_cache_check_suppress(cache, message, sizeof(message));
84
281
    reset_fuzz_allocator();
85
86
281
    entry = flb_log_cache_exists(cache, message, sizeof(message));
87
281
    if (entry != NULL) {
88
0
        abort();
89
0
    }
90
91
    /* A failed growth must leave the cache entry valid for a later retry. */
92
281
    flb_log_cache_check_suppress(cache, message, sizeof(message));
93
281
    entry = flb_log_cache_exists(cache, message, sizeof(message));
94
281
    if (entry == NULL) {
95
0
        abort();
96
0
    }
97
281
}
98
#endif
99
100
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
101
281
{
102
281
    int entries;
103
281
    int timeout;
104
281
    struct flb_log_cache *cache;
105
106
281
    if (size == 0) {
107
0
        return 0;
108
0
    }
109
110
281
    entries = (data[0] % MAX_CACHE_ENTRIES) + 1;
111
281
    timeout = data[0];
112
113
281
#ifdef FLB_HAVE_TESTS_OSSFUZZ
114
281
    silence_expected_allocation_errors();
115
281
    exercise_cache_create_allocation_failures(timeout, entries);
116
281
    reset_fuzz_allocator();
117
281
#endif
118
119
281
    cache = flb_log_cache_create(timeout, entries);
120
281
    if (cache == NULL) {
121
0
        return 0;
122
0
    }
123
124
281
#ifdef FLB_HAVE_TESTS_OSSFUZZ
125
281
    exercise_message_allocation_failure(cache, data[0]);
126
281
#endif
127
128
281
    if (size > 1) {
129
274
        flb_log_cache_check_suppress(cache, (char *) &data[1], size - 1);
130
274
        flb_log_cache_check_suppress(cache, (char *) &data[1], size - 1);
131
274
    }
132
133
281
#if SIZE_MAX > INT_MAX
134
281
    flb_log_cache_check_suppress(cache, (char *) data, (size_t) INT_MAX + 1);
135
281
#endif
136
137
281
    flb_log_cache_destroy(cache);
138
281
    return 0;
139
281
}