Coverage Report

Created: 2026-06-10 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwebp/tests/fuzzer/nalloc.h
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
#ifndef WEBP_TESTS_FUZZER_NALLOC_H_
26
#define WEBP_TESTS_FUZZER_NALLOC_H_
27
28
#if defined(WEBP_FUZZER_ENABLE_NALLOC)
29
30
#if defined(__clang__) && defined(__has_feature)
31
#if __has_feature(address_sanitizer)
32
#define NALLOC_ASAN 1
33
#endif
34
#endif
35
36
#include <errno.h>
37
#include <stdbool.h>
38
#include <stdint.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <string.h>
42
43
#ifdef __cplusplus
44
extern "C" {
45
#endif
46
47
static const uint32_t nalloc_crc32_table[] = {
48
    0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
49
    0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
50
    0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
51
    0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
52
    0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
53
    0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
54
    0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
55
    0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
56
    0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
57
    0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
58
    0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
59
    0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
60
    0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
61
    0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
62
    0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
63
    0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
64
    0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
65
    0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
66
    0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
67
    0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
68
    0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
69
    0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
70
    0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
71
    0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
72
    0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
73
    0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
74
    0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
75
    0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
76
    0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
77
    0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
78
    0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
79
    0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
80
    0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
81
    0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
82
    0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
83
    0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
84
    0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
85
    0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
86
    0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
87
    0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
88
    0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
89
    0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
90
    0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
91
92
// Nallocfuzz data to take a decision
93
uint32_t nalloc_random_state = 0;
94
__thread unsigned int nalloc_running = 0;
95
bool nalloc_initialized = false;
96
uint32_t nalloc_runs = 0;
97
98
// Nalloc fuzz parameters
99
uint32_t nalloc_bitmask = 0xFF;
100
bool nalloc_random_bitmask = true;
101
uint32_t nalloc_magic = 0x294cee63;
102
bool nalloc_verbose = false;
103
104
#ifdef NALLOC_ASAN
105
extern void __sanitizer_print_stack_trace(void);
106
#endif
107
108
// Generic init, using env variables to get parameters
109
29.1k
void nalloc_init(const char* prog) {
110
29.1k
  if (nalloc_initialized) {
111
29.1k
    return;
112
29.1k
  }
113
8
  nalloc_initialized = true;
114
8
  char* bitmask = getenv("NALLOC_FREQ");
115
8
  if (bitmask) {
116
4
    int shift = atoi(bitmask);
117
4
    if (shift > 0 && shift < 31) {
118
0
      nalloc_bitmask = 1 << shift;
119
0
      nalloc_random_bitmask = false;
120
4
    } else if (shift == 0) {
121
0
      nalloc_random_bitmask = false;
122
0
      nalloc_bitmask = 0;
123
0
    }
124
4
  } else if (prog == NULL || strstr(prog, "nalloc") == NULL) {
125
4
    nalloc_random_bitmask = false;
126
4
    nalloc_bitmask = 0;
127
4
    return;
128
4
  }
129
130
4
  char* magic = getenv("NALLOC_MAGIC");
131
4
  if (magic) {
132
0
    nalloc_magic = (uint32_t)strtol(magic, NULL, 0);
133
0
  }
134
135
4
  char* verbose = getenv("NALLOC_VERBOSE");
136
4
  if (verbose) {
137
0
    nalloc_verbose = true;
138
0
  }
139
4
}
140
141
// add one byte to the CRC
142
90.7M
static inline void nalloc_random_update(uint8_t b) {
143
90.7M
  nalloc_random_state =
144
90.7M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
90.7M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
90.7M
}
imageio_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
34.7M
static inline void nalloc_random_update(uint8_t b) {
143
34.7M
  nalloc_random_state =
144
34.7M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
34.7M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
34.7M
}
webp_info_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
9.58M
static inline void nalloc_random_update(uint8_t b) {
143
9.58M
  nalloc_random_state =
144
9.58M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
9.58M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
9.58M
}
animdecoder_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
25.4M
static inline void nalloc_random_update(uint8_t b) {
143
25.4M
  nalloc_random_state =
144
25.4M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
25.4M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
25.4M
}
anim_util_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
20.9M
static inline void nalloc_random_update(uint8_t b) {
143
20.9M
  nalloc_random_state =
144
20.9M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
20.9M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
20.9M
}
Unexecuted instantiation: dec_fuzzer.cc:nalloc_random_update(unsigned char)
147
148
// Start the failure injections, using a buffer as seed
149
29.1k
static int nalloc_start(const uint8_t* data, size_t size) {
150
29.1k
  if (nalloc_random_bitmask) {
151
12.6k
    if (nalloc_random_state & 0x10) {
152
6.39k
      nalloc_bitmask = 0xFFFFFFFF;
153
6.39k
    } else {
154
6.29k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
6.29k
    }
156
16.4k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
16.4k
    return 0;
159
16.4k
  }
160
12.6k
  nalloc_random_state = 0;
161
90.6M
  for (size_t i = 0; i < size; i++) {
162
90.6M
    nalloc_random_update(data[i]);
163
90.6M
  }
164
12.6k
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
12.6k
  nalloc_runs++;
169
12.6k
  return 1;
170
12.6k
}
imageio_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
11.9k
static int nalloc_start(const uint8_t* data, size_t size) {
150
11.9k
  if (nalloc_random_bitmask) {
151
5.64k
    if (nalloc_random_state & 0x10) {
152
2.81k
      nalloc_bitmask = 0xFFFFFFFF;
153
2.83k
    } else {
154
2.83k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
2.83k
    }
156
6.34k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
6.34k
    return 0;
159
6.34k
  }
160
5.64k
  nalloc_random_state = 0;
161
34.6M
  for (size_t i = 0; i < size; i++) {
162
34.6M
    nalloc_random_update(data[i]);
163
34.6M
  }
164
5.64k
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
5.64k
  nalloc_runs++;
169
5.64k
  return 1;
170
5.64k
}
webp_info_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
1.42k
static int nalloc_start(const uint8_t* data, size_t size) {
150
1.42k
  if (nalloc_random_bitmask) {
151
174
    if (nalloc_random_state & 0x10) {
152
99
      nalloc_bitmask = 0xFFFFFFFF;
153
99
    } else {
154
75
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
75
    }
156
1.25k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
1.25k
    return 0;
159
1.25k
  }
160
174
  nalloc_random_state = 0;
161
9.58M
  for (size_t i = 0; i < size; i++) {
162
9.58M
    nalloc_random_update(data[i]);
163
9.58M
  }
164
174
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
174
  nalloc_runs++;
169
174
  return 1;
170
174
}
animdecoder_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
8.27k
static int nalloc_start(const uint8_t* data, size_t size) {
150
8.27k
  if (nalloc_random_bitmask) {
151
3.75k
    if (nalloc_random_state & 0x10) {
152
1.88k
      nalloc_bitmask = 0xFFFFFFFF;
153
1.88k
    } else {
154
1.86k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
1.86k
    }
156
4.52k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
4.52k
    return 0;
159
4.52k
  }
160
3.75k
  nalloc_random_state = 0;
161
25.4M
  for (size_t i = 0; i < size; i++) {
162
25.4M
    nalloc_random_update(data[i]);
163
25.4M
  }
164
3.75k
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
3.75k
  nalloc_runs++;
169
3.75k
  return 1;
170
3.75k
}
anim_util_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
7.44k
static int nalloc_start(const uint8_t* data, size_t size) {
150
7.44k
  if (nalloc_random_bitmask) {
151
3.12k
    if (nalloc_random_state & 0x10) {
152
1.59k
      nalloc_bitmask = 0xFFFFFFFF;
153
1.59k
    } else {
154
1.52k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
1.52k
    }
156
4.32k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
4.32k
    return 0;
159
4.32k
  }
160
3.12k
  nalloc_random_state = 0;
161
20.9M
  for (size_t i = 0; i < size; i++) {
162
20.9M
    nalloc_random_update(data[i]);
163
20.9M
  }
164
3.12k
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
3.12k
  nalloc_runs++;
169
3.12k
  return 1;
170
3.12k
}
Unexecuted instantiation: dec_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
171
172
// Stop the failure injections
173
29.1k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
imageio_fuzzer.cc:nalloc_end()
Line
Count
Source
173
11.9k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
webp_info_fuzzer.cc:nalloc_end()
Line
Count
Source
173
1.42k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
animdecoder_fuzzer.cc:nalloc_end()
Line
Count
Source
173
8.27k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
anim_util_fuzzer.cc:nalloc_end()
Line
Count
Source
173
7.44k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
Unexecuted instantiation: dec_fuzzer.cc:nalloc_end()
174
175
5.51k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
5.51k
  if (nalloc_verbose) {
177
0
    fprintf(stderr, "failed %s(%zu) \n", op, size);
178
#ifdef NALLOC_ASAN
179
    __sanitizer_print_stack_trace();
180
#endif
181
0
  }
182
183
5.51k
  return false;
184
5.51k
}
imageio_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
Line
Count
Source
175
1.92k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
1.92k
  if (nalloc_verbose) {
177
0
    fprintf(stderr, "failed %s(%zu) \n", op, size);
178
#ifdef NALLOC_ASAN
179
    __sanitizer_print_stack_trace();
180
#endif
181
0
  }
182
183
1.92k
  return false;
184
1.92k
}
Unexecuted instantiation: webp_info_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
animdecoder_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
Line
Count
Source
175
1.92k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
1.92k
  if (nalloc_verbose) {
177
0
    fprintf(stderr, "failed %s(%zu) \n", op, size);
178
#ifdef NALLOC_ASAN
179
    __sanitizer_print_stack_trace();
180
#endif
181
0
  }
182
183
1.92k
  return false;
184
1.92k
}
anim_util_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
Line
Count
Source
175
1.66k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
1.66k
  if (nalloc_verbose) {
177
0
    fprintf(stderr, "failed %s(%zu) \n", op, size);
178
#ifdef NALLOC_ASAN
179
    __sanitizer_print_stack_trace();
180
#endif
181
0
  }
182
183
1.66k
  return false;
184
1.66k
}
Unexecuted instantiation: dec_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
185
186
//
187
1.43M
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
1.43M
  if (nalloc_runs == 0) {
190
1.13M
    return false;
191
1.13M
  }
192
301k
  if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
193
    // do not fail allocations outside of fuzzer input
194
    // and do not fail inside of this function
195
219k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
219k
    return false;
197
219k
  }
198
81.8k
  nalloc_random_update((uint8_t)size);
199
81.8k
  if (size >= 0x100) {
200
49.8k
    nalloc_random_update((uint8_t)(size >> 8));
201
49.8k
    if (size >= 0x10000) {
202
3.93k
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
3.93k
    }
205
49.8k
  }
206
81.8k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
5.51k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
5.51k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
5.51k
    return true;
213
5.51k
  }
214
76.3k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
76.3k
  return false;
216
81.8k
}
imageio_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
470k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
470k
  if (nalloc_runs == 0) {
190
376k
    return false;
191
376k
  }
192
94.3k
  if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
193
    // do not fail allocations outside of fuzzer input
194
    // and do not fail inside of this function
195
76.3k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
76.3k
    return false;
197
76.3k
  }
198
18.0k
  nalloc_random_update((uint8_t)size);
199
18.0k
  if (size >= 0x100) {
200
13.6k
    nalloc_random_update((uint8_t)(size >> 8));
201
13.6k
    if (size >= 0x10000) {
202
1.84k
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
1.84k
    }
205
13.6k
  }
206
18.0k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
1.92k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
1.92k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
1.92k
    return true;
213
1.92k
  }
214
16.1k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
16.1k
  return false;
216
18.0k
}
webp_info_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
228k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
228k
  if (nalloc_runs == 0) {
190
195k
    return false;
191
195k
  }
192
33.1k
  if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
193
    // do not fail allocations outside of fuzzer input
194
    // and do not fail inside of this function
195
33.1k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
33.1k
    return false;
197
33.1k
  }
198
0
  nalloc_random_update((uint8_t)size);
199
0
  if (size >= 0x100) {
200
0
    nalloc_random_update((uint8_t)(size >> 8));
201
0
    if (size >= 0x10000) {
202
0
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
0
    }
205
0
  }
206
0
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
0
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
0
    __sync_fetch_and_sub(&nalloc_running, 1);
212
0
    return true;
213
0
  }
214
0
  __sync_fetch_and_sub(&nalloc_running, 1);
215
0
  return false;
216
0
}
animdecoder_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
419k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
419k
  if (nalloc_runs == 0) {
190
325k
    return false;
191
325k
  }
192
93.5k
  if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
193
    // do not fail allocations outside of fuzzer input
194
    // and do not fail inside of this function
195
70.1k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
70.1k
    return false;
197
70.1k
  }
198
23.3k
  nalloc_random_update((uint8_t)size);
199
23.3k
  if (size >= 0x100) {
200
14.8k
    nalloc_random_update((uint8_t)(size >> 8));
201
14.8k
    if (size >= 0x10000) {
202
849
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
849
    }
205
14.8k
  }
206
23.3k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
1.92k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
1.92k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
1.92k
    return true;
213
1.92k
  }
214
21.4k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
21.4k
  return false;
216
23.3k
}
anim_util_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
315k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
315k
  if (nalloc_runs == 0) {
190
235k
    return false;
191
235k
  }
192
80.7k
  if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
193
    // do not fail allocations outside of fuzzer input
194
    // and do not fail inside of this function
195
40.2k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
40.2k
    return false;
197
40.2k
  }
198
40.4k
  nalloc_random_update((uint8_t)size);
199
40.4k
  if (size >= 0x100) {
200
21.3k
    nalloc_random_update((uint8_t)(size >> 8));
201
21.3k
    if (size >= 0x10000) {
202
1.24k
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
1.24k
    }
205
21.3k
  }
206
40.4k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
1.66k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
1.66k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
1.66k
    return true;
213
1.66k
  }
214
38.8k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
38.8k
  return false;
216
40.4k
}
dec_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
781
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
781
  if (nalloc_runs == 0) {
190
781
    return false;
191
781
  }
192
0
  if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
193
    // do not fail allocations outside of fuzzer input
194
    // and do not fail inside of this function
195
0
    __sync_fetch_and_sub(&nalloc_running, 1);
196
0
    return false;
197
0
  }
198
0
  nalloc_random_update((uint8_t)size);
199
0
  if (size >= 0x100) {
200
0
    nalloc_random_update((uint8_t)(size >> 8));
201
0
    if (size >= 0x10000) {
202
0
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
0
    }
205
0
  }
206
0
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
0
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
0
    __sync_fetch_and_sub(&nalloc_running, 1);
212
0
    return true;
213
0
  }
214
0
  __sync_fetch_and_sub(&nalloc_running, 1);
215
0
  return false;
216
0
}
217
218
// ASAN interceptor for libc routines
219
#ifdef NALLOC_ASAN
220
extern void* __interceptor_malloc(size_t);
221
extern void* __interceptor_calloc(size_t, size_t);
222
extern void* __interceptor_realloc(void*, size_t);
223
extern void* __interceptor_reallocarray(void*, size_t, size_t);
224
225
extern ssize_t __interceptor_read(int, void*, size_t);
226
extern ssize_t __interceptor_write(int, const void*, size_t);
227
extern ssize_t __interceptor_recv(int, void*, size_t, int);
228
extern ssize_t __interceptor_send(int, const void*, size_t, int);
229
230
#define nalloc_malloc(s) __interceptor_malloc(s)
231
#define nalloc_calloc(s, n) __interceptor_calloc(s, n)
232
#define nalloc_realloc(p, s) __interceptor_realloc(p, s)
233
#define nalloc_reallocarray(p, s, n) __interceptor_reallocarray(p, s, n)
234
235
#define nalloc_read(f, b, s) __interceptor_read(f, b, s)
236
#define nalloc_write(f, b, s) __interceptor_write(f, b, s)
237
#define nalloc_recv(f, b, s, x) __interceptor_recv(f, b, s, x)
238
#define nalloc_send(f, b, s, x) __interceptor_send(f, b, s, x)
239
240
#else
241
extern void* __libc_malloc(size_t);
242
extern void* __libc_calloc(size_t, size_t);
243
extern void* __libc_realloc(void*, size_t);
244
extern void* __libc_reallocarray(void*, size_t, size_t);
245
246
extern ssize_t __read(int, void*, size_t);
247
extern ssize_t __write(int, const void*, size_t);
248
extern ssize_t __recv(int, void*, size_t, int);
249
extern ssize_t __send(int, const void*, size_t, int);
250
251
1.32M
#define nalloc_malloc(s) __libc_malloc(s)
252
93.0k
#define nalloc_calloc(s, n) __libc_calloc(s, n)
253
13.6k
#define nalloc_realloc(p, s) __libc_realloc(p, s)
254
0
#define nalloc_reallocarray(p, s, n) __libc_reallocarray(p, s, n)
255
256
0
#define nalloc_read(f, b, s) __read(f, b, s)
257
0
#define nalloc_write(f, b, s) __write(f, b, s)
258
0
#define nalloc_recv(f, b, s, x) __recv(f, b, s, x)
259
0
#define nalloc_send(f, b, s, x) __send(f, b, s, x)
260
#endif
261
262
// nalloc standard function overwrites with pseudo-random failures
263
0
ssize_t read(int fd, void* buf, size_t count) {
264
0
  if (nalloc_fail(count, "read")) {
265
0
    errno = EIO;
266
0
    return -1;
267
0
  }
268
0
  return nalloc_read(fd, buf, count);
269
0
}
270
271
0
ssize_t write(int fd, const void* buf, size_t count) {
272
0
  if (nalloc_fail(count, "write")) {
273
0
    errno = EIO;
274
0
    return -1;
275
0
  }
276
0
  return nalloc_write(fd, buf, count);
277
0
}
278
279
0
ssize_t recv(int fd, void* buf, size_t count, int flags) {
280
0
  if (nalloc_fail(count, "recv")) {
281
0
    errno = EIO;
282
0
    return -1;
283
0
  }
284
0
  return nalloc_recv(fd, buf, count, flags);
285
0
}
286
287
0
ssize_t send(int fd, const void* buf, size_t count, int flags) {
288
0
  if (nalloc_fail(count, "send")) {
289
0
    errno = EIO;
290
0
    return -1;
291
0
  }
292
0
  return nalloc_send(fd, buf, count, flags);
293
0
}
294
295
97.1k
void* calloc(size_t nmemb, size_t size) {
296
97.1k
  if (nalloc_fail(size, "calloc")) {
297
4.08k
    errno = ENOMEM;
298
4.08k
    return NULL;
299
4.08k
  }
300
93.0k
  return nalloc_calloc(nmemb, size);
301
97.1k
}
302
303
1.32M
void* malloc(size_t size) {
304
1.32M
  if (nalloc_fail(size, "malloc")) {
305
1.42k
    errno = ENOMEM;
306
1.42k
    return NULL;
307
1.42k
  }
308
1.32M
  return nalloc_malloc(size);
309
1.32M
}
310
311
13.6k
void* realloc(void* ptr, size_t size) {
312
13.6k
  if (nalloc_fail(size, "realloc")) {
313
0
    errno = ENOMEM;
314
0
    return NULL;
315
0
  }
316
13.6k
  return nalloc_realloc(ptr, size);
317
13.6k
}
318
319
0
void* reallocarray(void* ptr, size_t nmemb, size_t size) {
320
0
  if (nalloc_fail(size, "reallocarray")) {
321
0
    errno = ENOMEM;
322
0
    return NULL;
323
0
  }
324
0
  return nalloc_reallocarray(ptr, nmemb, size);
325
0
}
326
327
#ifdef __cplusplus
328
}  // extern "C" {
329
#endif
330
331
#else  // defined(WEBP_FUZZER_ENABLE_NALLOC)
332
#define nalloc_init(x)
333
#define nalloc_start(x, y)
334
#define nalloc_end()
335
#endif  // defined(WEBP_FUZZER_ENABLE_NALLOC)
336
337
#endif  // WEBP_TESTS_FUZZER_NALLOC_H_