fuzz_plugin_name.h (14426B)
1 /* 2 This file is part of libextractor. 3 Copyright (C) 2026 Christian Grothoff 4 5 libextractor is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published 7 by the Free Software Foundation; either version 3, or (at your 8 option) any later version. 9 10 libextractor is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with libextractor; see the file COPYING. If not, write to the 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 /** 21 * @file fuzz/fuzz_plugin_name.h 22 * @brief per-plugin compile-time configuration of fuzz_plugin.c 23 * @author Christian Grothoff 24 * 25 * fuzz_plugin.c is compiled once per plugin. The Makefile passes two 26 * defines per target: 27 * 28 * -DLE_FUZZ_PLUGIN=gif the plugin's short name, used to build the 29 * symbol names EXTRACTOR_gif_extract_method() 30 * and EXTRACTOR_gif_options() 31 * -DLE_FUZZ_ID=GIF selects the format description below 32 * 33 * The description is only used by the *generator* (the built-in driver's 34 * structure-aware input synthesiser). It is not a correctness 35 * constraint: getting it wrong costs coverage, never soundness, and a 36 * plugin with no entry here simply gets random bytes. 37 * 38 * To add a plugin: give it an LE_ID_* number, add the `#elif` block with 39 * its magic and body shape, and add the target to Makefile.am. 40 */ 41 #ifndef LE_FUZZ_PLUGIN_NAME_H 42 #define LE_FUZZ_PLUGIN_NAME_H 1 43 44 #ifndef LE_FUZZ_PLUGIN 45 #error "fuzz_plugin.c must be compiled with -DLE_FUZZ_PLUGIN=<short name>" 46 #endif 47 #ifndef LE_FUZZ_ID 48 #error "fuzz_plugin.c must be compiled with -DLE_FUZZ_ID=<ID>" 49 #endif 50 51 #define LE_FUZZ_CAT2(a, b) a ## b 52 #define LE_FUZZ_CAT(a, b) LE_FUZZ_CAT2 (a, b) 53 #define LE_FUZZ_STR2(a) # a 54 #define LE_FUZZ_STR(a) LE_FUZZ_STR2 (a) 55 56 /** 57 * The plugin's short name as a string literal, e.g. "gif". 58 */ 59 #define LE_FUZZ_PLUGIN_STR LE_FUZZ_STR (LE_FUZZ_PLUGIN) 60 61 /** 62 * Name of the plugin's mandatory entry point. 63 */ 64 #define LE_FUZZ_EXTRACT_METHOD \ 65 LE_FUZZ_CAT (LE_FUZZ_CAT (EXTRACTOR_, LE_FUZZ_PLUGIN), _extract_method) 66 67 /** 68 * Name of the plugin's optional configuration hook. 69 */ 70 #define LE_FUZZ_OPTIONS_METHOD \ 71 LE_FUZZ_CAT (LE_FUZZ_CAT (EXTRACTOR_, LE_FUZZ_PLUGIN), _options) 72 73 74 /* Body shapes; must match enum le_fuzz_shape in fuzz_plugin.c. They are 75 spelled as plain integers here because this header is included before 76 that enum exists. */ 77 #define LE_SHAPE_RAW 0 78 #define LE_SHAPE_CHUNK_BE 1 79 #define LE_SHAPE_CHUNK_LE 2 80 #define LE_SHAPE_TEXT 3 81 #define LE_SHAPE_ZIP 4 82 83 #define LE_ID_APPLEFILE 1 84 #define LE_ID_ARCHIVE 2 85 #define LE_ID_DEB 3 86 #define LE_ID_DVI 4 87 #define LE_ID_ELF 5 88 #define LE_ID_FLAC 6 89 #define LE_ID_GIF 7 90 #define LE_ID_HTML 8 91 #define LE_ID_IT 9 92 #define LE_ID_JPEG 10 93 #define LE_ID_MAN 11 94 #define LE_ID_MIME 12 95 #define LE_ID_MPEG 13 96 #define LE_ID_MSOFFICE 14 97 #define LE_ID_NSF 15 98 #define LE_ID_NSFE 16 99 #define LE_ID_ODF 17 100 #define LE_ID_OGG 18 101 #define LE_ID_PNG 19 102 #define LE_ID_PS 20 103 #define LE_ID_QT 21 104 #define LE_ID_REAL 22 105 #define LE_ID_RIFF 23 106 #define LE_ID_RTF 24 107 #define LE_ID_S3M 25 108 #define LE_ID_SID 26 109 #define LE_ID_TIFF 27 110 #define LE_ID_WAV 28 111 #define LE_ID_XM 29 112 #define LE_ID_ZIP 30 113 #define LE_ID_OLE2 31 114 #define LE_ID_THUMBNAILFFMPEG 32 115 #define LE_ID_PREVIEWOPUS 33 116 #define LE_ID_PECOFF 34 117 #define LE_ID_LNK 35 118 #define LE_ID_SQLITE 36 119 #define LE_ID_TAR 37 120 #define LE_ID_ISO9660 38 121 #define LE_ID_DISKIMAGE 39 122 #define LE_ID_HEIF 40 123 #define LE_ID_WEBP 41 124 #define LE_ID_PLIST 42 125 #define LE_ID_ID3 43 126 #define LE_ID_GPX 44 127 #define LE_ID_KML 45 128 #define LE_ID_GEOTIFF 46 129 #define LE_ID_MBOX 47 130 #define LE_ID_APK 48 131 #define LE_ID_EBOOK 49 132 #define LE_ID_PDF 60 133 #define LE_ID_THUMBNAILGST 70 134 135 #define LE_FUZZ_IDVAL LE_FUZZ_CAT (LE_ID_, LE_FUZZ_ID) 136 137 #if LE_FUZZ_IDVAL == LE_ID_APPLEFILE 138 /* AppleSingle / AppleDouble: big-endian magic 0x00051600 / 0x00051607 */ 139 #define LE_FUZZ_MAGIC "\x00\x05\x16\x00\x00\x02\x00\x00" 140 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 141 142 #elif LE_FUZZ_IDVAL == LE_ID_ARCHIVE 143 #define LE_FUZZ_MAGIC "!<arch>\n" 144 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT 145 146 #elif LE_FUZZ_IDVAL == LE_ID_DEB 147 #define LE_FUZZ_MAGIC "!<arch>\ndebian-binary " 148 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT 149 150 #elif LE_FUZZ_IDVAL == LE_ID_DVI 151 /* DVI preamble: 0xF7 0x02 */ 152 #define LE_FUZZ_MAGIC "\xf7\x02" 153 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 154 #define LE_FUZZ_CONFIGS NULL, "fulltext" 155 156 #elif LE_FUZZ_IDVAL == LE_ID_PDF 157 /* the interesting inputs are real documents: seed the corpus with 158 testdata/pdf_*.pdf (make_seed_corpus.sh does) */ 159 #define LE_FUZZ_MAGIC "%PDF-1.4\n" 160 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT 161 #define LE_FUZZ_CONFIGS NULL, "fulltext" 162 163 #elif LE_FUZZ_IDVAL == LE_ID_ELF 164 #define LE_FUZZ_MAGIC "\x7f" "ELF\x01\x01\x01\x00" 165 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 166 167 #elif LE_FUZZ_IDVAL == LE_ID_FLAC 168 #define LE_FUZZ_MAGIC "fLaC" 169 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE 170 171 #elif LE_FUZZ_IDVAL == LE_ID_GIF 172 #define LE_FUZZ_MAGIC "GIF89a" 173 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 174 175 #elif LE_FUZZ_IDVAL == LE_ID_HTML 176 #define LE_FUZZ_MAGIC "<!DOCTYPE html>\n<html>" 177 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT 178 #define LE_FUZZ_CONFIGS NULL, "fulltext" 179 180 #elif LE_FUZZ_IDVAL == LE_ID_IT 181 /* Impulse Tracker module */ 182 #define LE_FUZZ_MAGIC "IMPM" 183 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 184 185 #elif LE_FUZZ_IDVAL == LE_ID_JPEG 186 #define LE_FUZZ_MAGIC "\xff\xd8\xff\xe0\x00\x10JFIF\x00" 187 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 188 189 #elif LE_FUZZ_IDVAL == LE_ID_MAN 190 #define LE_FUZZ_MAGIC ".TH " 191 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT 192 193 #elif LE_FUZZ_IDVAL == LE_ID_MIME 194 /* libmagic sniffs everything; no useful magic of our own */ 195 #define LE_FUZZ_MAGIC "" 196 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 197 198 #elif LE_FUZZ_IDVAL == LE_ID_THUMBNAILFFMPEG 199 /* Ogg, which is what the media plugins are tested against; libmagic has 200 to recognize it as video/* or the plugin declines to look at all */ 201 #define LE_FUZZ_MAGIC "OggS\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00" 202 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 203 #define LE_FUZZ_CONFIGS NULL, "srt:en", "gallery:4", \ 204 "gallery:9,format=png,srt:de", "size=32,gallery:100" 205 206 #elif LE_FUZZ_IDVAL == LE_ID_THUMBNAILGST 207 /* Matroska (EBML header with DocType "matroska"), what the srt and 208 gallery options are tested against; libmagic has to call it video/* 209 or the plugin declines to look at all */ 210 #define LE_FUZZ_MAGIC \ 211 "\x1a\x45\xdf\xa3\xa3\x42\x86\x81\x01\x42\xf7\x81\x01\x42\xf2" \ 212 "\x81\x04\x42\xf3\x81\x08\x42\x82\x88matroska\x42\x87\x81\x04" \ 213 "\x42\x85\x81\x02" 214 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 215 /* srt and gallery raise the default deadline to 60s; a hostile file can 216 stall GStreamer's preroll for all of it, which the harness watchdog 217 (20s) would report as a hang, so the deadline is lowered explicitly */ 218 #define LE_FUZZ_CONFIGS NULL, "srt:en,deadline=5000", \ 219 "gallery:4,deadline=5000", \ 220 "gallery:9,format=png,srt:de,deadline=5000", \ 221 "size=32,gallery:100,deadline=5000" 222 /* GStreamer never frees its registry, type system and thread pools; 223 only suppress leaks with a GStreamer frame on the stack, so that 224 leaks in the plugin's own glue are still reported */ 225 #define LE_FUZZ_LSAN_SUPPRESSIONS \ 226 "leak:libgstreamer-1.0.so\n" \ 227 "leak:libgstbase-1.0.so\n" \ 228 "leak:/gstreamer-1.0/\n" 229 230 #elif LE_FUZZ_IDVAL == LE_ID_PECOFF 231 /* MZ header; the PE header offset lives at 0x3c */ 232 /* carries a valid e_lfanew at 0x3c pointing at the "PE\0\0" signature; 233 without it every generated input dies at the second check */ 234 #define LE_FUZZ_MAGIC \ 235 "\x4d\x5a" \ 236 "\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e" \ 237 "\x40\x00\x00\x00\x50\x45\x00\x00" 238 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 239 240 #elif LE_FUZZ_IDVAL == LE_ID_LNK 241 /* header size 0x4c followed by the shell link CLSID */ 242 #define LE_FUZZ_MAGIC \ 243 "\x4c\x00\x00\x00\x01\x14\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46" 244 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 245 246 #elif LE_FUZZ_IDVAL == LE_ID_SQLITE 247 /* the header is the first 100 bytes */ 248 #define LE_FUZZ_MAGIC "SQLite format 3\x00" 249 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 250 251 #elif LE_FUZZ_IDVAL == LE_ID_TAR 252 /* the ustar magic is at offset 257, so the prefix only seeds the name field */ 253 #define LE_FUZZ_MAGIC "testfile\x00" 254 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 255 256 #elif LE_FUZZ_IDVAL == LE_ID_ISO9660 257 /* the primary volume descriptor is at offset 32768, out of reach of a prefix */ 258 #define LE_FUZZ_MAGIC "\x01" "CD001" 259 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 260 261 #elif LE_FUZZ_IDVAL == LE_ID_DISKIMAGE 262 /* qcow2; the VMDK/VHD/VHDX branches are reached from the corpus */ 263 #define LE_FUZZ_MAGIC "QFI\xfb\x00\x00\x00\x03" 264 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 265 266 #elif LE_FUZZ_IDVAL == LE_ID_HEIF 267 /* ISO base media file format: big-endian length-prefixed boxes */ 268 #define LE_FUZZ_MAGIC "\x00\x00\x00\x18" "ftypheic\x00\x00\x00\x00mif1heic" 269 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE 270 271 #elif LE_FUZZ_IDVAL == LE_ID_WEBP 272 /* RIFF: little-endian length-prefixed chunks */ 273 #define LE_FUZZ_MAGIC "RIFF\x00\x00\x00\x00WEBPVP8X" 274 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_LE 275 276 #elif LE_FUZZ_IDVAL == LE_ID_PLIST 277 /* the trailer is the last 32 bytes */ 278 #define LE_FUZZ_MAGIC "bplist00" 279 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 280 281 #elif LE_FUZZ_IDVAL == LE_ID_ID3 282 /* ID3v2 header with a synchsafe size */ 283 #define LE_FUZZ_MAGIC "ID3\x03\x00\x00\x00\x00\x00\x00" 284 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 285 286 #elif LE_FUZZ_IDVAL == LE_ID_GPX 287 #define LE_FUZZ_MAGIC \ 288 "<?xml version=\"1.0\"?>\n<gpx version=\"1.1\" creator=\"x\">" 289 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT 290 291 #elif LE_FUZZ_IDVAL == LE_ID_KML 292 #define LE_FUZZ_MAGIC \ 293 "<?xml version=\"1.0\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\">" 294 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT 295 296 #elif LE_FUZZ_IDVAL == LE_ID_GEOTIFF 297 /* little-endian classic TIFF; the geo tags live in the IFD */ 298 #define LE_FUZZ_MAGIC "II\x2a\x00\x08\x00\x00\x00" 299 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 300 301 #elif LE_FUZZ_IDVAL == LE_ID_MBOX 302 /* the envelope line alone is rejected: the plugin also requires a 303 well-formed header block behind it */ 304 #define LE_FUZZ_MAGIC \ 305 "From a@b Mon Jan 1 00:00:00 2024\n" \ 306 "From: a@b\nDate: 1 Jan 2024 00:00:00 +0000\n" 307 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT 308 309 #elif LE_FUZZ_IDVAL == LE_ID_APK 310 /* LE_SHAPE_ZIP synthesises the whole container, so a magic prefix 311 would sit in front of it and invalidate every local header 312 offset; the zip harness leaves it empty for the same reason */ 313 #define LE_FUZZ_MAGIC "" 314 #define LE_FUZZ_SHAPE LE_SHAPE_ZIP 315 316 #elif LE_FUZZ_IDVAL == LE_ID_EBOOK 317 /* EPUB; the MOBI branch has its "BOOKMOBI" magic at offset 60 and 318 cannot be expressed as a prefix, so seed the corpus with 319 testdata/ebook_test.mobi to reach it */ 320 #define LE_FUZZ_MAGIC "" 321 #define LE_FUZZ_SHAPE LE_SHAPE_ZIP 322 #define LE_FUZZ_CONFIGS NULL, "fulltext" 323 324 #elif LE_FUZZ_IDVAL == LE_ID_PREVIEWOPUS 325 #define LE_FUZZ_MAGIC "OggS\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00" 326 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 327 328 #elif LE_FUZZ_IDVAL == LE_ID_MPEG 329 #define LE_FUZZ_MAGIC "\x00\x00\x01\xba" 330 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 331 332 #elif LE_FUZZ_IDVAL == LE_ID_MSOFFICE 333 /* OOXML is a ZIP */ 334 #define LE_FUZZ_MAGIC "" 335 #define LE_FUZZ_SHAPE LE_SHAPE_ZIP 336 337 #elif LE_FUZZ_IDVAL == LE_ID_NSF 338 #define LE_FUZZ_MAGIC "NESM\x1a\x01" 339 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 340 341 #elif LE_FUZZ_IDVAL == LE_ID_NSFE 342 #define LE_FUZZ_MAGIC "NSFE" 343 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE 344 345 #elif LE_FUZZ_IDVAL == LE_ID_ODF 346 #define LE_FUZZ_MAGIC "" 347 #define LE_FUZZ_SHAPE LE_SHAPE_ZIP 348 #define LE_FUZZ_CONFIGS NULL, "fulltext" 349 350 #elif LE_FUZZ_IDVAL == LE_ID_OGG 351 #define LE_FUZZ_MAGIC "OggS\x00\x02" 352 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 353 354 #elif LE_FUZZ_IDVAL == LE_ID_OLE2 355 #define LE_FUZZ_MAGIC "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1" 356 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 357 #define LE_FUZZ_CONFIGS NULL, "fulltext" 358 359 #elif LE_FUZZ_IDVAL == LE_ID_PNG 360 #define LE_FUZZ_MAGIC "\x89PNG\r\n\x1a\n" 361 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE 362 363 #elif LE_FUZZ_IDVAL == LE_ID_PS 364 #define LE_FUZZ_MAGIC "%!PS-Adobe-3.0\n" 365 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT 366 367 #elif LE_FUZZ_IDVAL == LE_ID_QT 368 /* QuickTime: size + 'moov' at the very start is the easy way in */ 369 #define LE_FUZZ_MAGIC "\x00\x00\x00\x08moov" 370 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE 371 372 #elif LE_FUZZ_IDVAL == LE_ID_REAL 373 #define LE_FUZZ_MAGIC ".RMF\x00\x00\x00\x12" 374 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE 375 376 #elif LE_FUZZ_IDVAL == LE_ID_RIFF 377 #define LE_FUZZ_MAGIC "RIFF" 378 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_LE 379 380 #elif LE_FUZZ_IDVAL == LE_ID_RTF 381 #define LE_FUZZ_MAGIC "{\\rtf1" 382 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT 383 384 #elif LE_FUZZ_IDVAL == LE_ID_S3M 385 /* the 'SCRM' tag lives at offset 0x2c, so the magic here is the whole 386 leading header up to and including it */ 387 #define LE_FUZZ_MAGIC \ 388 "fuzz s3m module\x00" "\x1a\x10\x00\x00" \ 389 "\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ 390 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "SCRM" 391 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 392 393 #elif LE_FUZZ_IDVAL == LE_ID_SID 394 #define LE_FUZZ_MAGIC "PSID\x00\x02\x00\x7c\x00\x7c" 395 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 396 397 #elif LE_FUZZ_IDVAL == LE_ID_TIFF 398 #define LE_FUZZ_MAGIC "II\x2a\x00\x08\x00\x00\x00" 399 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 400 401 #elif LE_FUZZ_IDVAL == LE_ID_WAV 402 #define LE_FUZZ_MAGIC "RIFF" 403 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_LE 404 405 #elif LE_FUZZ_IDVAL == LE_ID_XM 406 #define LE_FUZZ_MAGIC "Extended Module: " 407 #define LE_FUZZ_SHAPE LE_SHAPE_RAW 408 409 #elif LE_FUZZ_IDVAL == LE_ID_ZIP 410 #define LE_FUZZ_MAGIC "" 411 #define LE_FUZZ_SHAPE LE_SHAPE_ZIP 412 413 #else 414 #error "no format description for this LE_FUZZ_ID; add one above" 415 #endif 416 417 #endif /* LE_FUZZ_PLUGIN_NAME_H */