Coverage Report

Created: 2025-10-10 07:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libssh/tests/fuzz/nallocinc.c
Line
Count
Source
1
/*
2
 MIT License
3
4
 Copyright (c) 2025 Catena cyber
5
6
 Permission is hereby granted, free of charge, to any person obtaining a copy
7
 of this software and associated documentation files (the "Software"), to deal
8
 in the Software without restriction, including without limitation the rights
9
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 copies of the Software, and to permit persons to whom the Software is
11
 furnished to do so, subject to the following conditions:
12
13
 The above copyright notice and this permission notice shall be included in all
14
 copies or substantial portions of the Software.
15
16
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 SOFTWARE.
23
*/
24
25
/* Nalloc fuzz : framework to make allocations and IO fail while fuzzing */
26
27
/* Environment variables to control nalloc fuzz behavior :
28
 * NALLOC_VERBOSE: set it to log failed allocations with their stacktraces
29
 * NALLOC_FREQ: set it to control how frequently allocations fail
30
 *  value 0 disables nalloc (no allocations fail)
31
 *  value 1..31 : allocations fail always (1) or very rarely (31 -> 1 / 2^31)
32
 *  value 32 : allocations fail at a random rate between 5 and 20 for each run
33
 */
34
#if defined(__clang__) && defined(__has_feature)
35
#if __has_feature(address_sanitizer)
36
#define NALLOC_ASAN 1
37
#endif
38
#endif
39
40
#include <errno.h>
41
#include <stdbool.h>
42
#include <stdint.h>
43
#include <stdio.h>
44
#include <stdlib.h>
45
#include <string.h>
46
47
#ifdef __cplusplus
48
extern "C" {
49
#endif
50
51
static const uint32_t nalloc_crc32_table[] = {
52
    0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
53
    0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
54
    0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
55
    0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
56
    0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
57
    0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
58
    0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
59
    0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
60
    0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
61
    0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
62
    0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
63
    0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
64
    0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
65
    0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
66
    0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
67
    0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
68
    0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
69
    0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
70
    0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
71
    0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
72
    0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
73
    0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
74
    0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
75
    0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
76
    0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
77
    0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
78
    0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
79
    0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
80
    0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
81
    0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
82
    0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
83
    0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
84
    0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
85
    0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
86
    0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
87
    0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
88
    0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
89
    0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
90
    0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
91
    0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
92
    0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
93
    0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
94
    0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
95
96
// Nallocfuzz data to take a decision
97
uint32_t nalloc_random_state = 0;
98
__thread unsigned int nalloc_running = 0;
99
bool nalloc_initialized = false;
100
uint32_t nalloc_runs = 0;
101
102
// Nalloc fuzz parameters
103
uint32_t nalloc_bitmask = 0xFF;
104
bool nalloc_random_bitmask = true;
105
uint32_t nalloc_magic = 0x294cee63;
106
bool nalloc_verbose = false;
107
108
#ifdef NALLOC_ASAN
109
extern void __sanitizer_print_stack_trace(void);
110
#endif
111
112
// Generic init, using env variables to get parameters
113
void nalloc_init(const char *prog)
114
32
{
115
32
    if (nalloc_initialized) {
116
0
        return;
117
0
    }
118
32
    nalloc_initialized = true;
119
32
    char *bitmask = getenv("NALLOC_FREQ");
120
32
    if (bitmask) {
121
0
        int shift = atoi(bitmask);
122
0
        if (shift > 0 && shift < 31) {
123
0
            nalloc_bitmask = 1 << shift;
124
0
            nalloc_random_bitmask = false;
125
0
        } else if (shift == 0) {
126
0
            nalloc_random_bitmask = false;
127
0
            nalloc_bitmask = 0;
128
0
        }
129
32
    } else if (prog == NULL || strstr(prog, "nalloc") == NULL) {
130
16
        nalloc_random_bitmask = false;
131
16
        nalloc_bitmask = 0;
132
16
        return;
133
16
    }
134
135
16
    char *verbose = getenv("NALLOC_VERBOSE");
136
16
    if (verbose) {
137
0
        nalloc_verbose = true;
138
0
    }
139
16
}
140
141
// add one byte to the CRC
142
static inline void nalloc_random_update(uint8_t b)
143
86.1M
{
144
86.1M
    nalloc_random_state =
145
86.1M
        ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
146
86.1M
        nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
147
86.1M
}
ssh_client_config_fuzzer.c:nalloc_random_update
Line
Count
Source
143
12.1M
{
144
12.1M
    nalloc_random_state =
145
12.1M
        ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
146
12.1M
        nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
147
12.1M
}
ssh_pubkey_fuzzer.c:nalloc_random_update
Line
Count
Source
143
25.0M
{
144
25.0M
    nalloc_random_state =
145
25.0M
        ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
146
25.0M
        nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
147
25.0M
}
ssh_known_hosts_fuzzer.c:nalloc_random_update
Line
Count
Source
143
5.31M
{
144
5.31M
    nalloc_random_state =
145
5.31M
        ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
146
5.31M
        nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
147
5.31M
}
ssh_privkey_fuzzer.c:nalloc_random_update
Line
Count
Source
143
11.9M
{
144
11.9M
    nalloc_random_state =
145
11.9M
        ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
146
11.9M
        nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
147
11.9M
}
ssh_client_fuzzer.c:nalloc_random_update
Line
Count
Source
143
6.48M
{
144
6.48M
    nalloc_random_state =
145
6.48M
        ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
146
6.48M
        nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
147
6.48M
}
ssh_server_fuzzer.c:nalloc_random_update
Line
Count
Source
143
5.30M
{
144
5.30M
    nalloc_random_state =
145
5.30M
        ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
146
5.30M
        nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
147
5.30M
}
ssh_bind_config_fuzzer.c:nalloc_random_update
Line
Count
Source
143
7.98M
{
144
7.98M
    nalloc_random_state =
145
7.98M
        ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
146
7.98M
        nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
147
7.98M
}
ssh_sshsig_fuzzer.c:nalloc_random_update
Line
Count
Source
143
11.8M
{
144
11.8M
    nalloc_random_state =
145
11.8M
        ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
146
11.8M
        nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
147
11.8M
}
148
149
// Start the failure injections, using a buffer as seed
150
static int nalloc_start(const uint8_t *data, size_t size)
151
19.0k
{
152
19.0k
    if (nalloc_random_bitmask) {
153
1.93k
        if (nalloc_random_state & 0x10) {
154
989
            nalloc_bitmask = 0xFFFFFFFF;
155
989
        } else {
156
945
            nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
157
945
        }
158
17.0k
    } else if (nalloc_bitmask == 0) {
159
        // nalloc disabled
160
17.0k
        return 2;
161
17.0k
    }
162
1.93k
    nalloc_random_state = 0;
163
85.7M
    for (size_t i = 0; i < size; i++) {
164
85.7M
        nalloc_random_update(data[i]);
165
85.7M
    }
166
1.93k
    if (__sync_fetch_and_add(&nalloc_running, 1)) {
167
0
        __sync_fetch_and_sub(&nalloc_running, 1);
168
0
        return 0;
169
0
    }
170
1.93k
    nalloc_runs++;
171
1.93k
    return 1;
172
1.93k
}
ssh_client_config_fuzzer.c:nalloc_start
Line
Count
Source
151
423
{
152
423
    if (nalloc_random_bitmask) {
153
18
        if (nalloc_random_state & 0x10) {
154
7
            nalloc_bitmask = 0xFFFFFFFF;
155
11
        } else {
156
11
            nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
157
11
        }
158
405
    } else if (nalloc_bitmask == 0) {
159
        // nalloc disabled
160
405
        return 2;
161
405
    }
162
18
    nalloc_random_state = 0;
163
12.0M
    for (size_t i = 0; i < size; i++) {
164
12.0M
        nalloc_random_update(data[i]);
165
12.0M
    }
166
18
    if (__sync_fetch_and_add(&nalloc_running, 1)) {
167
0
        __sync_fetch_and_sub(&nalloc_running, 1);
168
0
        return 0;
169
0
    }
170
18
    nalloc_runs++;
171
18
    return 1;
172
18
}
ssh_pubkey_fuzzer.c:nalloc_start
Line
Count
Source
151
2.71k
{
152
2.71k
    if (nalloc_random_bitmask) {
153
401
        if (nalloc_random_state & 0x10) {
154
214
            nalloc_bitmask = 0xFFFFFFFF;
155
214
        } else {
156
187
            nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
157
187
        }
158
2.31k
    } else if (nalloc_bitmask == 0) {
159
        // nalloc disabled
160
2.31k
        return 2;
161
2.31k
    }
162
401
    nalloc_random_state = 0;
163
25.0M
    for (size_t i = 0; i < size; i++) {
164
25.0M
        nalloc_random_update(data[i]);
165
25.0M
    }
166
401
    if (__sync_fetch_and_add(&nalloc_running, 1)) {
167
0
        __sync_fetch_and_sub(&nalloc_running, 1);
168
0
        return 0;
169
0
    }
170
401
    nalloc_runs++;
171
401
    return 1;
172
401
}
ssh_known_hosts_fuzzer.c:nalloc_start
Line
Count
Source
151
2.92k
{
152
2.92k
    if (nalloc_random_bitmask) {
153
472
        if (nalloc_random_state & 0x10) {
154
241
            nalloc_bitmask = 0xFFFFFFFF;
155
241
        } else {
156
231
            nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
157
231
        }
158
2.45k
    } else if (nalloc_bitmask == 0) {
159
        // nalloc disabled
160
2.45k
        return 2;
161
2.45k
    }
162
472
    nalloc_random_state = 0;
163
5.15M
    for (size_t i = 0; i < size; i++) {
164
5.15M
        nalloc_random_update(data[i]);
165
5.15M
    }
166
472
    if (__sync_fetch_and_add(&nalloc_running, 1)) {
167
0
        __sync_fetch_and_sub(&nalloc_running, 1);
168
0
        return 0;
169
0
    }
170
472
    nalloc_runs++;
171
472
    return 1;
172
472
}
ssh_privkey_fuzzer.c:nalloc_start
Line
Count
Source
151
190
{
152
190
    if (nalloc_random_bitmask) {
153
129
        if (nalloc_random_state & 0x10) {
154
71
            nalloc_bitmask = 0xFFFFFFFF;
155
71
        } else {
156
58
            nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
157
58
        }
158
129
    } else if (nalloc_bitmask == 0) {
159
        // nalloc disabled
160
61
        return 2;
161
61
    }
162
129
    nalloc_random_state = 0;
163
11.9M
    for (size_t i = 0; i < size; i++) {
164
11.9M
        nalloc_random_update(data[i]);
165
11.9M
    }
166
129
    if (__sync_fetch_and_add(&nalloc_running, 1)) {
167
0
        __sync_fetch_and_sub(&nalloc_running, 1);
168
0
        return 0;
169
0
    }
170
129
    nalloc_runs++;
171
129
    return 1;
172
129
}
ssh_client_fuzzer.c:nalloc_start
Line
Count
Source
151
3.69k
{
152
3.69k
    if (nalloc_random_bitmask) {
153
308
        if (nalloc_random_state & 0x10) {
154
158
            nalloc_bitmask = 0xFFFFFFFF;
155
158
        } else {
156
150
            nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
157
150
        }
158
3.38k
    } else if (nalloc_bitmask == 0) {
159
        // nalloc disabled
160
3.38k
        return 2;
161
3.38k
    }
162
308
    nalloc_random_state = 0;
163
6.44M
    for (size_t i = 0; i < size; i++) {
164
6.44M
        nalloc_random_update(data[i]);
165
6.44M
    }
166
308
    if (__sync_fetch_and_add(&nalloc_running, 1)) {
167
0
        __sync_fetch_and_sub(&nalloc_running, 1);
168
0
        return 0;
169
0
    }
170
308
    nalloc_runs++;
171
308
    return 1;
172
308
}
ssh_server_fuzzer.c:nalloc_start
Line
Count
Source
151
6.83k
{
152
6.83k
    if (nalloc_random_bitmask) {
153
123
        if (nalloc_random_state & 0x10) {
154
60
            nalloc_bitmask = 0xFFFFFFFF;
155
63
        } else {
156
63
            nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
157
63
        }
158
6.71k
    } else if (nalloc_bitmask == 0) {
159
        // nalloc disabled
160
6.71k
        return 2;
161
6.71k
    }
162
123
    nalloc_random_state = 0;
163
5.29M
    for (size_t i = 0; i < size; i++) {
164
5.29M
        nalloc_random_update(data[i]);
165
5.29M
    }
166
123
    if (__sync_fetch_and_add(&nalloc_running, 1)) {
167
0
        __sync_fetch_and_sub(&nalloc_running, 1);
168
0
        return 0;
169
0
    }
170
123
    nalloc_runs++;
171
123
    return 1;
172
123
}
ssh_bind_config_fuzzer.c:nalloc_start
Line
Count
Source
151
683
{
152
683
    if (nalloc_random_bitmask) {
153
15
        if (nalloc_random_state & 0x10) {
154
3
            nalloc_bitmask = 0xFFFFFFFF;
155
12
        } else {
156
12
            nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
157
12
        }
158
668
    } else if (nalloc_bitmask == 0) {
159
        // nalloc disabled
160
668
        return 2;
161
668
    }
162
15
    nalloc_random_state = 0;
163
7.97M
    for (size_t i = 0; i < size; i++) {
164
7.97M
        nalloc_random_update(data[i]);
165
7.97M
    }
166
15
    if (__sync_fetch_and_add(&nalloc_running, 1)) {
167
0
        __sync_fetch_and_sub(&nalloc_running, 1);
168
0
        return 0;
169
0
    }
170
15
    nalloc_runs++;
171
15
    return 1;
172
15
}
ssh_sshsig_fuzzer.c:nalloc_start
Line
Count
Source
151
1.54k
{
152
1.54k
    if (nalloc_random_bitmask) {
153
468
        if (nalloc_random_state & 0x10) {
154
235
            nalloc_bitmask = 0xFFFFFFFF;
155
235
        } else {
156
233
            nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
157
233
        }
158
1.07k
    } else if (nalloc_bitmask == 0) {
159
        // nalloc disabled
160
1.07k
        return 2;
161
1.07k
    }
162
468
    nalloc_random_state = 0;
163
11.8M
    for (size_t i = 0; i < size; i++) {
164
11.8M
        nalloc_random_update(data[i]);
165
11.8M
    }
166
468
    if (__sync_fetch_and_add(&nalloc_running, 1)) {
167
0
        __sync_fetch_and_sub(&nalloc_running, 1);
168
0
        return 0;
169
0
    }
170
468
    nalloc_runs++;
171
468
    return 1;
172
468
}
173
174
// Stop the failure injections
175
static void nalloc_end()
176
19.0k
{
177
19.0k
    __sync_fetch_and_sub(&nalloc_running, 1);
178
19.0k
}
ssh_client_config_fuzzer.c:nalloc_end
Line
Count
Source
176
423
{
177
423
    __sync_fetch_and_sub(&nalloc_running, 1);
178
423
}
ssh_pubkey_fuzzer.c:nalloc_end
Line
Count
Source
176
2.71k
{
177
2.71k
    __sync_fetch_and_sub(&nalloc_running, 1);
178
2.71k
}
ssh_known_hosts_fuzzer.c:nalloc_end
Line
Count
Source
176
2.92k
{
177
2.92k
    __sync_fetch_and_sub(&nalloc_running, 1);
178
2.92k
}
ssh_privkey_fuzzer.c:nalloc_end
Line
Count
Source
176
190
{
177
190
    __sync_fetch_and_sub(&nalloc_running, 1);
178
190
}
ssh_client_fuzzer.c:nalloc_end
Line
Count
Source
176
3.69k
{
177
3.69k
    __sync_fetch_and_sub(&nalloc_running, 1);
178
3.69k
}
ssh_server_fuzzer.c:nalloc_end
Line
Count
Source
176
6.83k
{
177
6.83k
    __sync_fetch_and_sub(&nalloc_running, 1);
178
6.83k
}
ssh_bind_config_fuzzer.c:nalloc_end
Line
Count
Source
176
683
{
177
683
    __sync_fetch_and_sub(&nalloc_running, 1);
178
683
}
ssh_sshsig_fuzzer.c:nalloc_end
Line
Count
Source
176
1.54k
{
177
1.54k
    __sync_fetch_and_sub(&nalloc_running, 1);
178
1.54k
}
179
180
static bool nalloc_backtrace_exclude(size_t size, const char *op)
181
994
{
182
994
    if (nalloc_verbose) {
183
0
        fprintf(stderr, "failed %s(%zu) \n", op, size);
184
#ifdef NALLOC_ASAN
185
        __sanitizer_print_stack_trace();
186
#endif
187
0
    }
188
189
994
    return false;
190
994
}
ssh_client_config_fuzzer.c:nalloc_backtrace_exclude
Line
Count
Source
181
11
{
182
11
    if (nalloc_verbose) {
183
0
        fprintf(stderr, "failed %s(%zu) \n", op, size);
184
#ifdef NALLOC_ASAN
185
        __sanitizer_print_stack_trace();
186
#endif
187
0
    }
188
189
    return false;
190
11
}
ssh_pubkey_fuzzer.c:nalloc_backtrace_exclude
Line
Count
Source
181
257
{
182
257
    if (nalloc_verbose) {
183
0
        fprintf(stderr, "failed %s(%zu) \n", op, size);
184
#ifdef NALLOC_ASAN
185
        __sanitizer_print_stack_trace();
186
#endif
187
0
    }
188
189
    return false;
190
257
}
ssh_known_hosts_fuzzer.c:nalloc_backtrace_exclude
Line
Count
Source
181
254
{
182
254
    if (nalloc_verbose) {
183
0
        fprintf(stderr, "failed %s(%zu) \n", op, size);
184
#ifdef NALLOC_ASAN
185
        __sanitizer_print_stack_trace();
186
#endif
187
0
    }
188
189
    return false;
190
254
}
ssh_privkey_fuzzer.c:nalloc_backtrace_exclude
Line
Count
Source
181
74
{
182
74
    if (nalloc_verbose) {
183
0
        fprintf(stderr, "failed %s(%zu) \n", op, size);
184
#ifdef NALLOC_ASAN
185
        __sanitizer_print_stack_trace();
186
#endif
187
0
    }
188
189
    return false;
190
74
}
ssh_client_fuzzer.c:nalloc_backtrace_exclude
Line
Count
Source
181
150
{
182
150
    if (nalloc_verbose) {
183
0
        fprintf(stderr, "failed %s(%zu) \n", op, size);
184
#ifdef NALLOC_ASAN
185
        __sanitizer_print_stack_trace();
186
#endif
187
0
    }
188
189
    return false;
190
150
}
ssh_server_fuzzer.c:nalloc_backtrace_exclude
Line
Count
Source
181
63
{
182
63
    if (nalloc_verbose) {
183
0
        fprintf(stderr, "failed %s(%zu) \n", op, size);
184
#ifdef NALLOC_ASAN
185
        __sanitizer_print_stack_trace();
186
#endif
187
0
    }
188
189
    return false;
190
63
}
ssh_bind_config_fuzzer.c:nalloc_backtrace_exclude
Line
Count
Source
181
7
{
182
7
    if (nalloc_verbose) {
183
0
        fprintf(stderr, "failed %s(%zu) \n", op, size);
184
#ifdef NALLOC_ASAN
185
        __sanitizer_print_stack_trace();
186
#endif
187
0
    }
188
189
    return false;
190
7
}
ssh_sshsig_fuzzer.c:nalloc_backtrace_exclude
Line
Count
Source
181
178
{
182
178
    if (nalloc_verbose) {
183
0
        fprintf(stderr, "failed %s(%zu) \n", op, size);
184
#ifdef NALLOC_ASAN
185
        __sanitizer_print_stack_trace();
186
#endif
187
0
    }
188
189
    return false;
190
178
}
191
192
//
193
static bool nalloc_fail(size_t size, const char *op)
194
18.0M
{
195
    // do not fail before thread init
196
18.0M
    if (nalloc_runs == 0) {
197
17.6M
        return false;
198
17.6M
    }
199
357k
    if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
200
        // do not fail allocations outside of fuzzer input
201
        // and do not fail inside of this function
202
12.7k
        __sync_fetch_and_sub(&nalloc_running, 1);
203
12.7k
        return false;
204
12.7k
    }
205
344k
    nalloc_random_update((uint8_t)size);
206
344k
    if (size >= 0x100) {
207
14.7k
        nalloc_random_update((uint8_t)(size >> 8));
208
14.7k
        if (size >= 0x10000) {
209
172
            nalloc_random_update((uint8_t)(size >> 16));
210
            // bigger may already fail or oom
211
172
        }
212
14.7k
    }
213
344k
    if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
214
994
        if (nalloc_backtrace_exclude(size, op)) {
215
0
            __sync_fetch_and_sub(&nalloc_running, 1);
216
0
            return false;
217
0
        }
218
994
        __sync_fetch_and_sub(&nalloc_running, 1);
219
994
        return true;
220
994
    }
221
343k
    __sync_fetch_and_sub(&nalloc_running, 1);
222
343k
    return false;
223
344k
}
ssh_client_config_fuzzer.c:nalloc_fail
Line
Count
Source
194
1.89M
{
195
    // do not fail before thread init
196
1.89M
    if (nalloc_runs == 0) {
197
1.76M
        return false;
198
1.76M
    }
199
127k
    if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
200
        // do not fail allocations outside of fuzzer input
201
        // and do not fail inside of this function
202
106
        __sync_fetch_and_sub(&nalloc_running, 1);
203
106
        return false;
204
106
    }
205
127k
    nalloc_random_update((uint8_t)size);
206
127k
    if (size >= 0x100) {
207
2.18k
        nalloc_random_update((uint8_t)(size >> 8));
208
2.18k
        if (size >= 0x10000) {
209
0
            nalloc_random_update((uint8_t)(size >> 16));
210
            // bigger may already fail or oom
211
0
        }
212
2.18k
    }
213
127k
    if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
214
11
        if (nalloc_backtrace_exclude(size, op)) {
215
0
            __sync_fetch_and_sub(&nalloc_running, 1);
216
0
            return false;
217
0
        }
218
11
        __sync_fetch_and_sub(&nalloc_running, 1);
219
11
        return true;
220
11
    }
221
127k
    __sync_fetch_and_sub(&nalloc_running, 1);
222
    return false;
223
127k
}
ssh_pubkey_fuzzer.c:nalloc_fail
Line
Count
Source
194
104k
{
195
    // do not fail before thread init
196
104k
    if (nalloc_runs == 0) {
197
98.7k
        return false;
198
98.7k
    }
199
5.22k
    if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
200
        // do not fail allocations outside of fuzzer input
201
        // and do not fail inside of this function
202
2.80k
        __sync_fetch_and_sub(&nalloc_running, 1);
203
2.80k
        return false;
204
2.80k
    }
205
2.41k
    nalloc_random_update((uint8_t)size);
206
2.41k
    if (size >= 0x100) {
207
929
        nalloc_random_update((uint8_t)(size >> 8));
208
929
        if (size >= 0x10000) {
209
52
            nalloc_random_update((uint8_t)(size >> 16));
210
            // bigger may already fail or oom
211
52
        }
212
929
    }
213
2.41k
    if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
214
257
        if (nalloc_backtrace_exclude(size, op)) {
215
0
            __sync_fetch_and_sub(&nalloc_running, 1);
216
0
            return false;
217
0
        }
218
257
        __sync_fetch_and_sub(&nalloc_running, 1);
219
257
        return true;
220
257
    }
221
2.15k
    __sync_fetch_and_sub(&nalloc_running, 1);
222
    return false;
223
2.41k
}
ssh_known_hosts_fuzzer.c:nalloc_fail
Line
Count
Source
194
1.24M
{
195
    // do not fail before thread init
196
1.24M
    if (nalloc_runs == 0) {
197
1.09M
        return false;
198
1.09M
    }
199
159k
    if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
200
        // do not fail allocations outside of fuzzer input
201
        // and do not fail inside of this function
202
3.82k
        __sync_fetch_and_sub(&nalloc_running, 1);
203
3.82k
        return false;
204
3.82k
    }
205
155k
    nalloc_random_update((uint8_t)size);
206
155k
    if (size >= 0x100) {
207
2.85k
        nalloc_random_update((uint8_t)(size >> 8));
208
2.85k
        if (size >= 0x10000) {
209
0
            nalloc_random_update((uint8_t)(size >> 16));
210
            // bigger may already fail or oom
211
0
        }
212
2.85k
    }
213
155k
    if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
214
254
        if (nalloc_backtrace_exclude(size, op)) {
215
0
            __sync_fetch_and_sub(&nalloc_running, 1);
216
0
            return false;
217
0
        }
218
254
        __sync_fetch_and_sub(&nalloc_running, 1);
219
254
        return true;
220
254
    }
221
155k
    __sync_fetch_and_sub(&nalloc_running, 1);
222
    return false;
223
155k
}
ssh_privkey_fuzzer.c:nalloc_fail
Line
Count
Source
194
7.07k
{
195
    // do not fail before thread init
196
7.07k
    if (nalloc_runs == 0) {
197
5.94k
        return false;
198
5.94k
    }
199
1.13k
    if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
200
        // do not fail allocations outside of fuzzer input
201
        // and do not fail inside of this function
202
646
        __sync_fetch_and_sub(&nalloc_running, 1);
203
646
        return false;
204
646
    }
205
486
    nalloc_random_update((uint8_t)size);
206
486
    if (size >= 0x100) {
207
80
        nalloc_random_update((uint8_t)(size >> 8));
208
80
        if (size >= 0x10000) {
209
22
            nalloc_random_update((uint8_t)(size >> 16));
210
            // bigger may already fail or oom
211
22
        }
212
80
    }
213
486
    if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
214
74
        if (nalloc_backtrace_exclude(size, op)) {
215
0
            __sync_fetch_and_sub(&nalloc_running, 1);
216
0
            return false;
217
0
        }
218
74
        __sync_fetch_and_sub(&nalloc_running, 1);
219
74
        return true;
220
74
    }
221
412
    __sync_fetch_and_sub(&nalloc_running, 1);
222
    return false;
223
486
}
ssh_client_fuzzer.c:nalloc_fail
Line
Count
Source
194
1.14M
{
195
    // do not fail before thread init
196
1.14M
    if (nalloc_runs == 0) {
197
1.10M
        return false;
198
1.10M
    }
199
37.2k
    if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
200
        // do not fail allocations outside of fuzzer input
201
        // and do not fail inside of this function
202
1.85k
        __sync_fetch_and_sub(&nalloc_running, 1);
203
1.85k
        return false;
204
1.85k
    }
205
35.3k
    nalloc_random_update((uint8_t)size);
206
35.3k
    if (size >= 0x100) {
207
6.49k
        nalloc_random_update((uint8_t)(size >> 8));
208
6.49k
        if (size >= 0x10000) {
209
48
            nalloc_random_update((uint8_t)(size >> 16));
210
            // bigger may already fail or oom
211
48
        }
212
6.49k
    }
213
35.3k
    if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
214
150
        if (nalloc_backtrace_exclude(size, op)) {
215
0
            __sync_fetch_and_sub(&nalloc_running, 1);
216
0
            return false;
217
0
        }
218
150
        __sync_fetch_and_sub(&nalloc_running, 1);
219
150
        return true;
220
150
    }
221
35.2k
    __sync_fetch_and_sub(&nalloc_running, 1);
222
    return false;
223
35.3k
}
ssh_server_fuzzer.c:nalloc_fail
Line
Count
Source
194
4.29M
{
195
    // do not fail before thread init
196
4.29M
    if (nalloc_runs == 0) {
197
4.28M
        return false;
198
4.28M
    }
199
9.96k
    if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
200
        // do not fail allocations outside of fuzzer input
201
        // and do not fail inside of this function
202
1.11k
        __sync_fetch_and_sub(&nalloc_running, 1);
203
1.11k
        return false;
204
1.11k
    }
205
8.84k
    nalloc_random_update((uint8_t)size);
206
8.84k
    if (size >= 0x100) {
207
1.87k
        nalloc_random_update((uint8_t)(size >> 8));
208
1.87k
        if (size >= 0x10000) {
209
10
            nalloc_random_update((uint8_t)(size >> 16));
210
            // bigger may already fail or oom
211
10
        }
212
1.87k
    }
213
8.84k
    if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
214
63
        if (nalloc_backtrace_exclude(size, op)) {
215
0
            __sync_fetch_and_sub(&nalloc_running, 1);
216
0
            return false;
217
0
        }
218
63
        __sync_fetch_and_sub(&nalloc_running, 1);
219
63
        return true;
220
63
    }
221
8.77k
    __sync_fetch_and_sub(&nalloc_running, 1);
222
    return false;
223
8.84k
}
ssh_bind_config_fuzzer.c:nalloc_fail
Line
Count
Source
194
9.28M
{
195
    // do not fail before thread init
196
9.28M
    if (nalloc_runs == 0) {
197
9.27M
        return false;
198
9.27M
    }
199
12.0k
    if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
200
        // do not fail allocations outside of fuzzer input
201
        // and do not fail inside of this function
202
89
        __sync_fetch_and_sub(&nalloc_running, 1);
203
89
        return false;
204
89
    }
205
11.9k
    nalloc_random_update((uint8_t)size);
206
11.9k
    if (size >= 0x100) {
207
17
        nalloc_random_update((uint8_t)(size >> 8));
208
17
        if (size >= 0x10000) {
209
0
            nalloc_random_update((uint8_t)(size >> 16));
210
            // bigger may already fail or oom
211
0
        }
212
17
    }
213
11.9k
    if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
214
7
        if (nalloc_backtrace_exclude(size, op)) {
215
0
            __sync_fetch_and_sub(&nalloc_running, 1);
216
0
            return false;
217
0
        }
218
7
        __sync_fetch_and_sub(&nalloc_running, 1);
219
7
        return true;
220
7
    }
221
11.9k
    __sync_fetch_and_sub(&nalloc_running, 1);
222
    return false;
223
11.9k
}
ssh_sshsig_fuzzer.c:nalloc_fail
Line
Count
Source
194
34.6k
{
195
    // do not fail before thread init
196
34.6k
    if (nalloc_runs == 0) {
197
30.4k
        return false;
198
30.4k
    }
199
4.24k
    if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
200
        // do not fail allocations outside of fuzzer input
201
        // and do not fail inside of this function
202
2.34k
        __sync_fetch_and_sub(&nalloc_running, 1);
203
2.34k
        return false;
204
2.34k
    }
205
1.90k
    nalloc_random_update((uint8_t)size);
206
1.90k
    if (size >= 0x100) {
207
349
        nalloc_random_update((uint8_t)(size >> 8));
208
349
        if (size >= 0x10000) {
209
40
            nalloc_random_update((uint8_t)(size >> 16));
210
            // bigger may already fail or oom
211
40
        }
212
349
    }
213
1.90k
    if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
214
178
        if (nalloc_backtrace_exclude(size, op)) {
215
0
            __sync_fetch_and_sub(&nalloc_running, 1);
216
0
            return false;
217
0
        }
218
178
        __sync_fetch_and_sub(&nalloc_running, 1);
219
178
        return true;
220
178
    }
221
1.72k
    __sync_fetch_and_sub(&nalloc_running, 1);
222
    return false;
223
1.90k
}
224
225
// ASAN interceptor for libc routines
226
#ifdef NALLOC_ASAN
227
extern void *__interceptor_malloc(size_t);
228
extern void *__interceptor_calloc(size_t, size_t);
229
extern void *__interceptor_realloc(void *, size_t);
230
extern void *__interceptor_reallocarray(void *, size_t, size_t);
231
232
extern ssize_t __interceptor_read(int, void *, size_t);
233
extern ssize_t __interceptor_write(int, const void *, size_t);
234
extern ssize_t __interceptor_recv(int, void *, size_t, int);
235
extern ssize_t __interceptor_send(int, const void *, size_t, int);
236
237
#define nalloc_malloc(s)             __interceptor_malloc(s)
238
#define nalloc_calloc(s, n)          __interceptor_calloc(s, n)
239
#define nalloc_realloc(p, s)         __interceptor_realloc(p, s)
240
#define nalloc_reallocarray(p, s, n) __interceptor_reallocarray(p, s, n)
241
242
#define nalloc_read(f, b, s)    __interceptor_read(f, b, s)
243
#define nalloc_write(f, b, s)   __interceptor_write(f, b, s)
244
#define nalloc_recv(f, b, s, x) __interceptor_recv(f, b, s, x)
245
#define nalloc_send(f, b, s, x) __interceptor_send(f, b, s, x)
246
247
#else
248
extern void *__libc_malloc(size_t);
249
extern void *__libc_calloc(size_t, size_t);
250
extern void *__libc_realloc(void *, size_t);
251
extern void *__libc_reallocarray(void *, size_t, size_t);
252
253
extern ssize_t __read(int, void *, size_t);
254
extern ssize_t __write(int, const void *, size_t);
255
extern ssize_t __recv(int, void *, size_t, int);
256
extern ssize_t __send(int, const void *, size_t, int);
257
258
16.3M
#define nalloc_malloc(s)             __libc_malloc(s)
259
1.07M
#define nalloc_calloc(s, n)          __libc_calloc(s, n)
260
556k
#define nalloc_realloc(p, s)         __libc_realloc(p, s)
261
0
#define nalloc_reallocarray(p, s, n) __libc_reallocarray(p, s, n)
262
263
0
#define nalloc_read(f, b, s)    __read(f, b, s)
264
2.71k
#define nalloc_write(f, b, s)   __write(f, b, s)
265
23.8k
#define nalloc_recv(f, b, s, x) __recv(f, b, s, x)
266
26.2k
#define nalloc_send(f, b, s, x) __send(f, b, s, x)
267
#endif
268
269
// nalloc standard function overwrites with pseudo-random failures
270
ssize_t read(int fd, void *buf, size_t count)
271
0
{
272
0
    if (nalloc_fail(count, "read")) {
273
0
        errno = EIO;
274
0
        return -1;
275
0
    }
276
0
    return nalloc_read(fd, buf, count);
277
0
}
278
279
ssize_t write(int fd, const void *buf, size_t count)
280
2.71k
{
281
2.71k
    if (nalloc_fail(count, "write")) {
282
0
        errno = EIO;
283
0
        return -1;
284
0
    }
285
2.71k
    return nalloc_write(fd, buf, count);
286
2.71k
}
287
288
ssize_t recv(int fd, void *buf, size_t count, int flags)
289
23.8k
{
290
23.8k
    if (nalloc_fail(count, "recv")) {
291
0
        errno = EIO;
292
0
        return -1;
293
0
    }
294
23.8k
    return nalloc_recv(fd, buf, count, flags);
295
23.8k
}
296
297
ssize_t send(int fd, const void *buf, size_t count, int flags)
298
26.2k
{
299
26.2k
    if (nalloc_fail(count, "send")) {
300
0
        errno = EIO;
301
0
        return -1;
302
0
    }
303
26.2k
    return nalloc_send(fd, buf, count, flags);
304
26.2k
}
305
306
void *calloc(size_t nmemb, size_t size)
307
1.07M
{
308
1.07M
    if (nalloc_fail(size, "calloc")) {
309
269
        errno = ENOMEM;
310
269
        return NULL;
311
269
    }
312
1.07M
    return nalloc_calloc(nmemb, size);
313
1.07M
}
314
315
void *malloc(size_t size)
316
16.3M
{
317
16.3M
    if (nalloc_fail(size, "malloc")) {
318
706
        errno = ENOMEM;
319
706
        return NULL;
320
706
    }
321
16.3M
    return nalloc_malloc(size);
322
16.3M
}
323
324
void *realloc(void *ptr, size_t size)
325
556k
{
326
556k
    if (nalloc_fail(size, "realloc")) {
327
19
        errno = ENOMEM;
328
19
        return NULL;
329
19
    }
330
556k
    return nalloc_realloc(ptr, size);
331
556k
}
332
333
void *reallocarray(void *ptr, size_t nmemb, size_t size)
334
0
{
335
0
    if (nalloc_fail(size, "reallocarray")) {
336
0
        errno = ENOMEM;
337
0
        return NULL;
338
0
    }
339
0
    return nalloc_reallocarray(ptr, nmemb, size);
340
0
}
341
342
#ifdef __cplusplus
343
} // extern "C" {
344
#endif