Coverage Report

Created: 2026-04-01 06:14

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.4k
void nalloc_init(const char* prog) {
110
25.4k
  if (nalloc_initialized) {
111
25.4k
    return;
112
25.4k
  }
113
10
  nalloc_initialized = true;
114
10
  char* bitmask = getenv("NALLOC_FREQ");
115
10
  if (bitmask) {
116
5
    int shift = atoi(bitmask);
117
5
    if (shift > 0 && shift < 31) {
118
0
      nalloc_bitmask = 1 << shift;
119
0
      nalloc_random_bitmask = false;
120
5
    } 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
5
  char* magic = getenv("NALLOC_MAGIC");
131
5
  if (magic) {
132
0
    nalloc_magic = (uint32_t)strtol(magic, NULL, 0);
133
0
  }
134
135
5
  char* verbose = getenv("NALLOC_VERBOSE");
136
5
  if (verbose) {
137
0
    nalloc_verbose = true;
138
0
  }
139
5
}
140
141
// add one byte to the CRC
142
86.7M
static inline void nalloc_random_update(uint8_t b) {
143
86.7M
  nalloc_random_state =
144
86.7M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
86.7M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
86.7M
}
imageio_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
33.9M
static inline void nalloc_random_update(uint8_t b) {
143
33.9M
  nalloc_random_state =
144
33.9M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
33.9M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
33.9M
}
webp_info_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
8.83M
static inline void nalloc_random_update(uint8_t b) {
143
8.83M
  nalloc_random_state =
144
8.83M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
8.83M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
8.83M
}
animdecoder_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
25.6M
static inline void nalloc_random_update(uint8_t b) {
143
25.6M
  nalloc_random_state =
144
25.6M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
25.6M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
25.6M
}
anim_util_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
593k
static inline void nalloc_random_update(uint8_t b) {
143
593k
  nalloc_random_state =
144
593k
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
593k
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
593k
}
dec_fuzzer.cc:nalloc_random_update(unsigned char)
Line
Count
Source
142
17.6M
static inline void nalloc_random_update(uint8_t b) {
143
17.6M
  nalloc_random_state =
144
17.6M
      ((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
145
17.6M
      nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
146
17.6M
}
147
148
// Start the failure injections, using a buffer as seed
149
25.4k
static int nalloc_start(const uint8_t* data, size_t size) {
150
25.4k
  if (nalloc_random_bitmask) {
151
10.8k
    if (nalloc_random_state & 0x10) {
152
5.41k
      nalloc_bitmask = 0xFFFFFFFF;
153
5.41k
    } else {
154
5.39k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
5.39k
    }
156
14.6k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
14.6k
    return 0;
159
14.6k
  }
160
10.8k
  nalloc_random_state = 0;
161
86.6M
  for (size_t i = 0; i < size; i++) {
162
86.6M
    nalloc_random_update(data[i]);
163
86.6M
  }
164
10.8k
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
10.8k
  nalloc_runs++;
169
10.8k
  return 1;
170
10.8k
}
imageio_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
10.4k
static int nalloc_start(const uint8_t* data, size_t size) {
150
10.4k
  if (nalloc_random_bitmask) {
151
4.25k
    if (nalloc_random_state & 0x10) {
152
2.11k
      nalloc_bitmask = 0xFFFFFFFF;
153
2.13k
    } else {
154
2.13k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
2.13k
    }
156
6.21k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
6.21k
    return 0;
159
6.21k
  }
160
4.25k
  nalloc_random_state = 0;
161
33.9M
  for (size_t i = 0; i < size; i++) {
162
33.9M
    nalloc_random_update(data[i]);
163
33.9M
  }
164
4.25k
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
4.25k
  nalloc_runs++;
169
4.25k
  return 1;
170
4.25k
}
webp_info_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
1.32k
static int nalloc_start(const uint8_t* data, size_t size) {
150
1.32k
  if (nalloc_random_bitmask) {
151
173
    if (nalloc_random_state & 0x10) {
152
85
      nalloc_bitmask = 0xFFFFFFFF;
153
88
    } else {
154
88
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
88
    }
156
1.15k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
1.15k
    return 0;
159
1.15k
  }
160
173
  nalloc_random_state = 0;
161
8.83M
  for (size_t i = 0; i < size; i++) {
162
8.83M
    nalloc_random_update(data[i]);
163
8.83M
  }
164
173
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
173
  nalloc_runs++;
169
173
  return 1;
170
173
}
animdecoder_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
7.74k
static int nalloc_start(const uint8_t* data, size_t size) {
150
7.74k
  if (nalloc_random_bitmask) {
151
3.19k
    if (nalloc_random_state & 0x10) {
152
1.55k
      nalloc_bitmask = 0xFFFFFFFF;
153
1.63k
    } else {
154
1.63k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
1.63k
    }
156
4.55k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
4.55k
    return 0;
159
4.55k
  }
160
3.19k
  nalloc_random_state = 0;
161
25.6M
  for (size_t i = 0; i < size; i++) {
162
25.6M
    nalloc_random_update(data[i]);
163
25.6M
  }
164
3.19k
  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.19k
  nalloc_runs++;
169
3.19k
  return 1;
170
3.19k
}
anim_util_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
1.54k
static int nalloc_start(const uint8_t* data, size_t size) {
150
1.54k
  if (nalloc_random_bitmask) {
151
866
    if (nalloc_random_state & 0x10) {
152
451
      nalloc_bitmask = 0xFFFFFFFF;
153
451
    } else {
154
415
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
415
    }
156
866
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
675
    return 0;
159
675
  }
160
866
  nalloc_random_state = 0;
161
583k
  for (size_t i = 0; i < size; i++) {
162
582k
    nalloc_random_update(data[i]);
163
582k
  }
164
866
  if (__sync_fetch_and_add(&nalloc_running, 1)) {
165
0
    __sync_fetch_and_sub(&nalloc_running, 1);
166
0
    return 0;
167
0
  }
168
866
  nalloc_runs++;
169
866
  return 1;
170
866
}
dec_fuzzer.cc:nalloc_start(unsigned char const*, unsigned long)
Line
Count
Source
149
4.40k
static int nalloc_start(const uint8_t* data, size_t size) {
150
4.40k
  if (nalloc_random_bitmask) {
151
2.32k
    if (nalloc_random_state & 0x10) {
152
1.19k
      nalloc_bitmask = 0xFFFFFFFF;
153
1.19k
    } else {
154
1.12k
      nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
155
1.12k
    }
156
2.32k
  } else if (nalloc_bitmask == 0) {
157
    // nalloc disabled
158
2.08k
    return 0;
159
2.08k
  }
160
2.32k
  nalloc_random_state = 0;
161
17.6M
  for (size_t i = 0; i < size; i++) {
162
17.6M
    nalloc_random_update(data[i]);
163
17.6M
  }
164
2.32k
  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.32k
  nalloc_runs++;
169
2.32k
  return 1;
170
2.32k
}
171
172
// Stop the failure injections
173
25.4k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
imageio_fuzzer.cc:nalloc_end()
Line
Count
Source
173
10.4k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
webp_info_fuzzer.cc:nalloc_end()
Line
Count
Source
173
1.32k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
animdecoder_fuzzer.cc:nalloc_end()
Line
Count
Source
173
7.74k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
anim_util_fuzzer.cc:nalloc_end()
Line
Count
Source
173
1.54k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
dec_fuzzer.cc:nalloc_end()
Line
Count
Source
173
4.40k
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
174
175
4.35k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
4.35k
  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
4.35k
  return false;
184
4.35k
}
imageio_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
Line
Count
Source
175
1.32k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
1.32k
  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.32k
  return false;
184
1.32k
}
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.62k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
1.62k
  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.62k
  return false;
184
1.62k
}
anim_util_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
Line
Count
Source
175
365
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
365
  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
365
  return false;
184
365
}
dec_fuzzer.cc:nalloc_backtrace_exclude(unsigned long, char const*)
Line
Count
Source
175
1.04k
static bool nalloc_backtrace_exclude(size_t size, const char* op) {
176
1.04k
  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.04k
  return false;
184
1.04k
}
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.17M
    return false;
191
1.17M
  }
192
262k
  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
212k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
212k
    return false;
197
212k
  }
198
49.7k
  nalloc_random_update((uint8_t)size);
199
49.7k
  if (size >= 0x100) {
200
33.1k
    nalloc_random_update((uint8_t)(size >> 8));
201
33.1k
    if (size >= 0x10000) {
202
3.20k
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
3.20k
    }
205
33.1k
  }
206
49.7k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
4.35k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
4.35k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
4.35k
    return true;
213
4.35k
  }
214
45.3k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
45.3k
  return false;
216
49.7k
}
imageio_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
434k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
434k
  if (nalloc_runs == 0) {
190
358k
    return false;
191
358k
  }
192
75.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
62.2k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
62.2k
    return false;
197
62.2k
  }
198
12.9k
  nalloc_random_update((uint8_t)size);
199
12.9k
  if (size >= 0x100) {
200
9.45k
    nalloc_random_update((uint8_t)(size >> 8));
201
9.45k
    if (size >= 0x10000) {
202
1.18k
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
1.18k
    }
205
9.45k
  }
206
12.9k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
1.32k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
1.32k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
1.32k
    return true;
213
1.32k
  }
214
11.6k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
11.6k
  return false;
216
12.9k
}
webp_info_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
225k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
225k
  if (nalloc_runs == 0) {
190
192k
    return false;
191
192k
  }
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
403k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
403k
  if (nalloc_runs == 0) {
190
321k
    return false;
191
321k
  }
192
82.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
62.7k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
62.7k
    return false;
197
62.7k
  }
198
19.3k
  nalloc_random_update((uint8_t)size);
199
19.3k
  if (size >= 0x100) {
200
12.4k
    nalloc_random_update((uint8_t)(size >> 8));
201
12.4k
    if (size >= 0x10000) {
202
622
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
622
    }
205
12.4k
  }
206
19.3k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
1.62k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
1.62k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
1.62k
    return true;
213
1.62k
  }
214
17.6k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
17.6k
  return false;
216
19.3k
}
anim_util_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
55.6k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
55.6k
  if (nalloc_runs == 0) {
190
38.4k
    return false;
191
38.4k
  }
192
17.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
10.7k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
10.7k
    return false;
197
10.7k
  }
198
6.42k
  nalloc_random_update((uint8_t)size);
199
6.42k
  if (size >= 0x100) {
200
3.59k
    nalloc_random_update((uint8_t)(size >> 8));
201
3.59k
    if (size >= 0x10000) {
202
389
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
389
    }
205
3.59k
  }
206
6.42k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
365
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
365
    __sync_fetch_and_sub(&nalloc_running, 1);
212
365
    return true;
213
365
  }
214
6.05k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
6.05k
  return false;
216
6.42k
}
dec_fuzzer.cc:nalloc_fail(unsigned long, char const*)
Line
Count
Source
187
313k
static bool nalloc_fail(size_t size, const char* op) {
188
  // do not fail before thread init
189
313k
  if (nalloc_runs == 0) {
190
259k
    return false;
191
259k
  }
192
54.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
43.6k
    __sync_fetch_and_sub(&nalloc_running, 1);
196
43.6k
    return false;
197
43.6k
  }
198
11.0k
  nalloc_random_update((uint8_t)size);
199
11.0k
  if (size >= 0x100) {
200
7.67k
    nalloc_random_update((uint8_t)(size >> 8));
201
7.67k
    if (size >= 0x10000) {
202
1.00k
      nalloc_random_update((uint8_t)(size >> 16));
203
      // bigger may already fail or oom
204
1.00k
    }
205
7.67k
  }
206
11.0k
  if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
207
1.04k
    if (nalloc_backtrace_exclude(size, op)) {
208
0
      __sync_fetch_and_sub(&nalloc_running, 1);
209
0
      return false;
210
0
    }
211
1.04k
    __sync_fetch_and_sub(&nalloc_running, 1);
212
1.04k
    return true;
213
1.04k
  }
214
10.0k
  __sync_fetch_and_sub(&nalloc_running, 1);
215
10.0k
  return false;
216
11.0k
}
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.36M
#define nalloc_malloc(s) __libc_malloc(s)
252
67.7k
#define nalloc_calloc(s, n) __libc_calloc(s, n)
253
10
#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
70.7k
void* calloc(size_t nmemb, size_t size) {
296
70.7k
  if (nalloc_fail(size, "calloc")) {
297
3.00k
    errno = ENOMEM;
298
3.00k
    return NULL;
299
3.00k
  }
300
67.7k
  return nalloc_calloc(nmemb, size);
301
70.7k
}
302
303
1.36M
void* malloc(size_t size) {
304
1.36M
  if (nalloc_fail(size, "malloc")) {
305
1.34k
    errno = ENOMEM;
306
1.34k
    return NULL;
307
1.34k
  }
308
1.36M
  return nalloc_malloc(size);
309
1.36M
}
310
311
10
void* realloc(void* ptr, size_t size) {
312
10
  if (nalloc_fail(size, "realloc")) {
313
0
    errno = ENOMEM;
314
0
    return NULL;
315
0
  }
316
10
  return nalloc_realloc(ptr, size);
317
10
}
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_