Coverage Report

Created: 2026-09-04 06:18

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
25.2k
void nalloc_init(const char* prog) {
110
25.2k
  if (nalloc_initialized) {
111
25.2k
    return;
112
25.2k
  }
113
9
  nalloc_initialized = true;
114
9
  char* bitmask = getenv("NALLOC_FREQ");
115
9
  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
5
  } else if (prog == NULL || strstr(prog, "nalloc") == NULL) {
125
5
    nalloc_random_bitmask = false;
126
5
    nalloc_bitmask = 0;
127
5
    return;
128
5
  }
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
100M
static inline void nalloc_random_update(uint8_t b) {
143
100M
  nalloc_random_state =
144
100M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
100M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
100M
}
imageio_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
35.2M
static inline void nalloc_random_update(uint8_t b) {
143
35.2M
  nalloc_random_state =
144
35.2M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
35.2M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
35.2M
}
webp_info_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
9.02M
static inline void nalloc_random_update(uint8_t b) {
143
9.02M
  nalloc_random_state =
144
9.02M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
9.02M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
9.02M
}
animdecoder_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
26.1M
static inline void nalloc_random_update(uint8_t b) {
143
26.1M
  nalloc_random_state =
144
26.1M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
26.1M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
26.1M
}
anim_util_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
29.7M
static inline void nalloc_random_update(uint8_t b) {
143
29.7M
  nalloc_random_state =
144
29.7M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
29.7M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
29.7M
}
Unexecuted instantiation: dec_fuzzer.cc:nalloc_random_update(unsigned char)
147
148
// Start the failure injections, using a buffer as seed
149
25.2k
static int nalloc_start(const uint8_t* data, size_t size) {
150
25.2k
  if (nalloc_random_bitmask) {
151
8.38k
    if (nalloc_random_state & 0x10) {
152
4.16k
      nalloc_bitmask = 0xFFFFFFFF;
153
4.21k
    } else {
154
4.21k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
4.21k
    }
156
16.8k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
16.8k
    return 0;
159
16.8k
  }
160
8.38k
  nalloc_random_state = 0;
161
100M
  for (size_t i = 0; i < size; i++) {
162
100M
    nalloc_random_update(data[i]);
163
100M
  }
164
8.38k
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
8.38k
  nalloc_runs++;
169
8.38k
  return 1;
170
8.38k
}
imageio_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
9.40k
static int nalloc_start(const uint8_t* data, size_t size) {
150
9.40k
  if (nalloc_random_bitmask) {
151
3.69k
    if (nalloc_random_state & 0x10) {
152
1.82k
      nalloc_bitmask = 0xFFFFFFFF;
153
1.86k
    } else {
154
1.86k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
1.86k
    }
156
5.70k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
5.70k
    return 0;
159
5.70k
  }
160
3.69k
  nalloc_random_state = 0;
161
35.2M
  for (size_t i = 0; i < size; i++) {
162
35.2M
    nalloc_random_update(data[i]);
163
35.2M
  }
164
3.69k
  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.69k
  nalloc_runs++;
169
3.69k
  return 1;
170
3.69k
}
webp_info_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
1.23k
static int nalloc_start(const uint8_t* data, size_t size) {
150
1.23k
  if (nalloc_random_bitmask) {
151
146
    if (nalloc_random_state & 0x10) {
152
74
      nalloc_bitmask = 0xFFFFFFFF;
153
74
    } else {
154
72
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
72
    }
156
1.09k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
1.09k
    return 0;
159
1.09k
  }
160
146
  nalloc_random_state = 0;
161
9.02M
  for (size_t i = 0; i < size; i++) {
162
9.02M
    nalloc_random_update(data[i]);
163
9.02M
  }
164
146
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
146
  nalloc_runs++;
169
146
  return 1;
170
146
}
animdecoder_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
6.31k
static int nalloc_start(const uint8_t* data, size_t size) {
150
6.31k
  if (nalloc_random_bitmask) {
151
2.07k
    if (nalloc_random_state & 0x10) {
152
1.03k
      nalloc_bitmask = 0xFFFFFFFF;
153
1.04k
    } else {
154
1.04k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
1.04k
    }
156
4.23k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
4.23k
    return 0;
159
4.23k
  }
160
2.07k
  nalloc_random_state = 0;
161
26.1M
  for (size_t i = 0; i < size; i++) {
162
26.1M
    nalloc_random_update(data[i]);
163
26.1M
  }
164
2.07k
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
2.07k
  nalloc_runs++;
169
2.07k
  return 1;
170
2.07k
}
anim_util_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
6.15k
static int nalloc_start(const uint8_t* data, size_t size) {
150
6.15k
  if (nalloc_random_bitmask) {
151
2.46k
    if (nalloc_random_state & 0x10) {
152
1.23k
      nalloc_bitmask = 0xFFFFFFFF;
153
1.23k
    } else {
154
1.23k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
1.23k
    }
156
3.68k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
3.68k
    return 0;
159
3.68k
  }
160
2.46k
  nalloc_random_state = 0;
161
29.7M
  for (size_t i = 0; i < size; i++) {
162
29.7M
    nalloc_random_update(data[i]);
163
29.7M
  }
164
2.46k
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
2.46k
  nalloc_runs++;
169
2.46k
  return 1;
170
2.46k
}
dec_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
2.12k
static int nalloc_start(const uint8_t* data, size_t size) {
150
2.12k
  if (nalloc_random_bitmask) {
151
0
    if (nalloc_random_state & 0x10) {
152
0
      nalloc_bitmask = 0xFFFFFFFF;
153
0
    } else {
154
0
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
0
    }
156
2.12k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
2.12k
    return 0;
159
2.12k
  }
160
0
  nalloc_random_state = 0;
161
0
  for (size_t i = 0; i < size; i++) {
162
0
    nalloc_random_update(data[i]);
163
0
  }
164
0
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
0
  nalloc_runs++;
169
0
  return 1;
170
0
}
171
172
// Stop the failure injections
173
25.2k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
imageio_fuzzer.cc:nalloc_end()
Line
Count
Source
173
9.40k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
webp_info_fuzzer.cc:nalloc_end()
Line
Count
Source
173
1.23k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
animdecoder_fuzzer.cc:nalloc_end()
Line
Count
Source
173
6.31k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
anim_util_fuzzer.cc:nalloc_end()
Line
Count
Source
173
6.15k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
dec_fuzzer.cc:nalloc_end()
Line
Count
Source
173
2.12k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
174
175
3.22k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
3.22k
  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
3.22k
  return false;
184
3.22k
}
imageio_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
Line
Count
Source
175
1.08k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
1.08k
  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.08k
  return false;
184
1.08k
}
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.00k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
1.00k
  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.00k
  return false;
184
1.00k
}
anim_util_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
Line
Count
Source
175
1.13k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
1.13k
  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.13k
  return false;
184
1.13k
}
Unexecuted instantiation: dec_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
185
186
//
187
1.52M
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
1.52M
  if (nalloc_runs == 0) {
190
1.27M
    return false;
191
1.27M
  }
192
254k
  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
190k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
190k
    return false;
197
190k
  }
198
63.6k
  nalloc_random_update((uint8_t)size);
199
63.6k
  if (size >= 0x100) {
200
37.8k
    nalloc_random_update((uint8_t)(size >> 8));
201
37.8k
    if (size >= 0x10000) {
202
2.68k
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
2.68k
    }
205
37.8k
  }
206
63.6k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
3.22k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
3.22k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
3.22k
    return true;
213
3.22k
  }
214
60.3k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
60.3k
  return false;
216
63.6k
}
imageio_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
407k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
407k
  if (nalloc_runs == 0) {
190
340k
    return false;
191
340k
  }
192
66.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
55.8k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
55.8k
    return false;
197
55.8k
  }
198
10.6k
  nalloc_random_update((uint8_t)size);
199
10.6k
  if (size >= 0x100) {
200
7.77k
    nalloc_random_update((uint8_t)(size >> 8));
201
7.77k
    if (size >= 0x10000) {
202
1.07k
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
1.07k
    }
205
7.77k
  }
206
10.6k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
1.08k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
1.08k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
1.08k
    return true;
213
1.08k
  }
214
9.60k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
9.60k
  return false;
216
10.6k
}
webp_info_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
220k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
220k
  if (nalloc_runs == 0) {
190
188k
    return false;
191
188k
  }
192
32.4k
  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
32.4k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
32.4k
    return false;
197
32.4k
  }
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
359k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
359k
  if (nalloc_runs == 0) {
190
295k
    return false;
191
295k
  }
192
63.8k
  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
50.9k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
50.9k
    return false;
197
50.9k
  }
198
12.9k
  nalloc_random_update((uint8_t)size);
199
12.9k
  if (size >= 0x100) {
200
8.27k
    nalloc_random_update((uint8_t)(size >> 8));
201
8.27k
    if (size >= 0x10000) {
202
448
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
448
    }
205
8.27k
  }
206
12.9k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
1.00k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
1.00k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
1.00k
    return true;
213
1.00k
  }
214
11.9k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
11.9k
  return false;
216
12.9k
}
anim_util_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
380k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
380k
  if (nalloc_runs == 0) {
190
288k
    return false;
191
288k
  }
192
91.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
51.6k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
51.6k
    return false;
197
51.6k
  }
198
40.0k
  nalloc_random_update((uint8_t)size);
199
40.0k
  if (size >= 0x100) {
200
21.7k
    nalloc_random_update((uint8_t)(size >> 8));
201
21.7k
    if (size >= 0x10000) {
202
1.16k
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
1.16k
    }
205
21.7k
  }
206
40.0k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
1.13k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
1.13k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
1.13k
    return true;
213
1.13k
  }
214
38.8k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
38.8k
  return false;
216
40.0k
}
dec_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
160k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
160k
  if (nalloc_runs == 0) {
190
160k
    return false;
191
160k
  }
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.43M
#define nalloc_malloc(s) __libc_malloc(s)
252
80.2k
#define nalloc_calloc(s, n) __libc_calloc(s, n)
253
13.7k
#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
82.6k
void* calloc(size_t nmemb, size_t size) {
296
82.6k
  if (nalloc_fail(size, "calloc")) {
297
2.40k
    errno = ENOMEM;
298
2.40k
    return NULL;
299
2.40k
  }
300
80.2k
  return nalloc_calloc(nmemb, size);
301
82.6k
}
302
303
1.43M
void* malloc(size_t size) {
304
1.43M
  if (nalloc_fail(size, "malloc")) {
305
826
    errno = ENOMEM;
306
826
    return NULL;
307
826
  }
308
1.43M
  return nalloc_malloc(size);
309
1.43M
}
310
311
13.7k
void* realloc(void* ptr, size_t size) {
312
13.7k
  if (nalloc_fail(size, "realloc")) {
313
0
    errno = ENOMEM;
314
0
    return NULL;
315
0
  }
316
13.7k
  return nalloc_realloc(ptr, size);
317
13.7k
}
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_