Coverage Report

Created: 2025-11-16 06:26

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
20.5k
void nalloc_init(const char* prog) {
110
20.5k
  if (nalloc_initialized) {
111
20.5k
    return;
112
20.5k
  }
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
63.3M
static inline void nalloc_random_update(uint8_t b) {
143
63.3M
  nalloc_random_state =
144
63.3M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
63.3M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
63.3M
}
imageio_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
33.4M
static inline void nalloc_random_update(uint8_t b) {
143
33.4M
  nalloc_random_state =
144
33.4M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
33.4M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
33.4M
}
webp_info_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
6.30M
static inline void nalloc_random_update(uint8_t b) {
143
6.30M
  nalloc_random_state =
144
6.30M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
6.30M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
6.30M
}
animdecoder_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
19.3M
static inline void nalloc_random_update(uint8_t b) {
143
19.3M
  nalloc_random_state =
144
19.3M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
19.3M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
19.3M
}
dec_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
4.24M
static inline void nalloc_random_update(uint8_t b) {
143
4.24M
  nalloc_random_state =
144
4.24M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
4.24M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
4.24M
}
147
148
// Start the failure injections, using a buffer as seed
149
20.5k
static int nalloc_start(const uint8_t* data, size_t size) {
150
20.5k
  if (nalloc_random_bitmask) {
151
7.75k
    if (nalloc_random_state & 0x10) {
152
3.88k
      nalloc_bitmask = 0xFFFFFFFF;
153
3.88k
    } else {
154
3.87k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
3.87k
    }
156
12.7k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
12.7k
    return 0;
159
12.7k
  }
160
7.75k
  nalloc_random_state = 0;
161
63.2M
  for (size_t i = 0; i < size; i++) {
162
63.2M
    nalloc_random_update(data[i]);
163
63.2M
  }
164
7.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
7.75k
  nalloc_runs++;
169
7.75k
  return 1;
170
7.75k
}
imageio_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
9.70k
static int nalloc_start(const uint8_t* data, size_t size) {
150
9.70k
  if (nalloc_random_bitmask) {
151
3.87k
    if (nalloc_random_state & 0x10) {
152
1.96k
      nalloc_bitmask = 0xFFFFFFFF;
153
1.96k
    } else {
154
1.91k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
1.91k
    }
156
5.83k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
5.83k
    return 0;
159
5.83k
  }
160
3.87k
  nalloc_random_state = 0;
161
33.4M
  for (size_t i = 0; i < size; i++) {
162
33.3M
    nalloc_random_update(data[i]);
163
33.3M
  }
164
3.87k
  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.87k
  nalloc_runs++;
169
3.87k
  return 1;
170
3.87k
}
webp_info_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
1.26k
static int nalloc_start(const uint8_t* data, size_t size) {
150
1.26k
  if (nalloc_random_bitmask) {
151
134
    if (nalloc_random_state & 0x10) {
152
56
      nalloc_bitmask = 0xFFFFFFFF;
153
78
    } else {
154
78
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
78
    }
156
1.12k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
1.12k
    return 0;
159
1.12k
  }
160
134
  nalloc_random_state = 0;
161
6.30M
  for (size_t i = 0; i < size; i++) {
162
6.30M
    nalloc_random_update(data[i]);
163
6.30M
  }
164
134
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
134
  nalloc_runs++;
169
134
  return 1;
170
134
}
animdecoder_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
5.82k
static int nalloc_start(const uint8_t* data, size_t size) {
150
5.82k
  if (nalloc_random_bitmask) {
151
2.23k
    if (nalloc_random_state & 0x10) {
152
1.09k
      nalloc_bitmask = 0xFFFFFFFF;
153
1.13k
    } else {
154
1.13k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
1.13k
    }
156
3.59k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
3.59k
    return 0;
159
3.59k
  }
160
2.23k
  nalloc_random_state = 0;
161
19.3M
  for (size_t i = 0; i < size; i++) {
162
19.3M
    nalloc_random_update(data[i]);
163
19.3M
  }
164
2.23k
  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.23k
  nalloc_runs++;
169
2.23k
  return 1;
170
2.23k
}
dec_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
3.76k
static int nalloc_start(const uint8_t* data, size_t size) {
150
3.76k
  if (nalloc_random_bitmask) {
151
1.52k
    if (nalloc_random_state & 0x10) {
152
775
      nalloc_bitmask = 0xFFFFFFFF;
153
775
    } else {
154
747
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
747
    }
156
2.24k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
2.24k
    return 0;
159
2.24k
  }
160
1.52k
  nalloc_random_state = 0;
161
4.23M
  for (size_t i = 0; i < size; i++) {
162
4.22M
    nalloc_random_update(data[i]);
163
4.22M
  }
164
1.52k
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
1.52k
  nalloc_runs++;
169
1.52k
  return 1;
170
1.52k
}
171
172
// Stop the failure injections
173
20.5k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
imageio_fuzzer.cc:nalloc_end()
Line
Count
Source
173
9.70k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
webp_info_fuzzer.cc:nalloc_end()
Line
Count
Source
173
1.26k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
animdecoder_fuzzer.cc:nalloc_end()
Line
Count
Source
173
5.82k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
dec_fuzzer.cc:nalloc_end()
Line
Count
Source
173
3.76k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
174
175
3.05k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
3.05k
  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.05k
  return false;
184
3.05k
}
imageio_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
Line
Count
Source
175
1.15k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
1.15k
  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.15k
  return false;
184
1.15k
}
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.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
}
dec_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
Line
Count
Source
175
768
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
768
  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
768
  return false;
184
768
}
185
186
//
187
1.24M
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
1.24M
  if (nalloc_runs == 0) {
190
1.03M
    return false;
191
1.03M
  }
192
209k
  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
172k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
172k
    return false;
197
172k
  }
198
36.8k
  nalloc_random_update((uint8_t)size);
199
36.8k
  if (size >= 0x100) {
200
25.7k
    nalloc_random_update((uint8_t)(size >> 8));
201
25.7k
    if (size >= 0x10000) {
202
2.09k
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
2.09k
    }
205
25.7k
  }
206
36.8k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
3.05k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
3.05k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
3.05k
    return true;
213
3.05k
  }
214
33.8k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
33.8k
  return false;
216
36.8k
}
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
336k
    return false;
191
336k
  }
192
70.2k
  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
58.5k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
58.5k
    return false;
197
58.5k
  }
198
11.7k
  nalloc_random_update((uint8_t)size);
199
11.7k
  if (size >= 0x100) {
200
8.79k
    nalloc_random_update((uint8_t)(size >> 8));
201
8.79k
    if (size >= 0x10000) {
202
1.03k
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
1.03k
    }
205
8.79k
  }
206
11.7k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
1.15k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
1.15k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
1.15k
    return true;
213
1.15k
  }
214
10.5k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
10.5k
  return false;
216
11.7k
}
webp_info_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
219k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
219k
  if (nalloc_runs == 0) {
190
188k
    return false;
191
188k
  }
192
31.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
31.4k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
31.4k
    return false;
197
31.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
327k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
327k
  if (nalloc_runs == 0) {
190
263k
    return false;
191
263k
  }
192
63.9k
  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
48.6k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
48.6k
    return false;
197
48.6k
  }
198
15.2k
  nalloc_random_update((uint8_t)size);
199
15.2k
  if (size >= 0x100) {
200
10.4k
    nalloc_random_update((uint8_t)(size >> 8));
201
10.4k
    if (size >= 0x10000) {
202
424
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
424
    }
205
10.4k
  }
206
15.2k
  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
14.1k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
14.1k
  return false;
216
15.2k
}
dec_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
286k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
286k
  if (nalloc_runs == 0) {
190
242k
    return false;
191
242k
  }
192
43.6k
  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.7k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
33.7k
    return false;
197
33.7k
  }
198
9.90k
  nalloc_random_update((uint8_t)size);
199
9.90k
  if (size >= 0x100) {
200
6.57k
    nalloc_random_update((uint8_t)(size >> 8));
201
6.57k
    if (size >= 0x10000) {
202
643
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
643
    }
205
6.57k
  }
206
9.90k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
768
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
768
    __sync_fetch_and_sub(&nalloc_running, 1);
212
768
    return true;
213
768
  }
214
9.13k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
9.13k
  return false;
216
9.90k
}
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.18M
#define nalloc_malloc(s) __libc_malloc(s)
252
51.6k
#define nalloc_calloc(s, n) __libc_calloc(s, n)
253
8
#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
53.6k
void* calloc(size_t nmemb, size_t size) {
296
53.6k
  if (nalloc_fail(size, "calloc")) {
297
1.96k
    errno = ENOMEM;
298
1.96k
    return NULL;
299
1.96k
  }
300
51.6k
  return nalloc_calloc(nmemb, size);
301
53.6k
}
302
303
1.18M
void* malloc(size_t size) {
304
1.18M
  if (nalloc_fail(size, "malloc")) {
305
1.09k
    errno = ENOMEM;
306
1.09k
    return NULL;
307
1.09k
  }
308
1.18M
  return nalloc_malloc(size);
309
1.18M
}
310
311
8
void* realloc(void* ptr, size_t size) {
312
8
  if (nalloc_fail(size, "realloc")) {
313
0
    errno = ENOMEM;
314
0
    return NULL;
315
0
  }
316
8
  return nalloc_realloc(ptr, size);
317
8
}
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_