libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

fuzz_plugin_name.h (12572B)


      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 
    133 #define LE_FUZZ_IDVAL LE_FUZZ_CAT (LE_ID_, LE_FUZZ_ID)
    134 
    135 #if LE_FUZZ_IDVAL == LE_ID_APPLEFILE
    136 /* AppleSingle / AppleDouble: big-endian magic 0x00051600 / 0x00051607 */
    137 #define LE_FUZZ_MAGIC "\x00\x05\x16\x00\x00\x02\x00\x00"
    138 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    139 
    140 #elif LE_FUZZ_IDVAL == LE_ID_ARCHIVE
    141 #define LE_FUZZ_MAGIC "!<arch>\n"
    142 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT
    143 
    144 #elif LE_FUZZ_IDVAL == LE_ID_DEB
    145 #define LE_FUZZ_MAGIC "!<arch>\ndebian-binary   "
    146 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT
    147 
    148 #elif LE_FUZZ_IDVAL == LE_ID_DVI
    149 /* DVI preamble: 0xF7 0x02 */
    150 #define LE_FUZZ_MAGIC "\xf7\x02"
    151 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    152 
    153 #elif LE_FUZZ_IDVAL == LE_ID_ELF
    154 #define LE_FUZZ_MAGIC "\x7f" "ELF\x01\x01\x01\x00"
    155 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    156 
    157 #elif LE_FUZZ_IDVAL == LE_ID_FLAC
    158 #define LE_FUZZ_MAGIC "fLaC"
    159 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE
    160 
    161 #elif LE_FUZZ_IDVAL == LE_ID_GIF
    162 #define LE_FUZZ_MAGIC "GIF89a"
    163 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    164 
    165 #elif LE_FUZZ_IDVAL == LE_ID_HTML
    166 #define LE_FUZZ_MAGIC "<!DOCTYPE html>\n<html>"
    167 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT
    168 
    169 #elif LE_FUZZ_IDVAL == LE_ID_IT
    170 /* Impulse Tracker module */
    171 #define LE_FUZZ_MAGIC "IMPM"
    172 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    173 
    174 #elif LE_FUZZ_IDVAL == LE_ID_JPEG
    175 #define LE_FUZZ_MAGIC "\xff\xd8\xff\xe0\x00\x10JFIF\x00"
    176 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    177 
    178 #elif LE_FUZZ_IDVAL == LE_ID_MAN
    179 #define LE_FUZZ_MAGIC ".TH "
    180 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT
    181 
    182 #elif LE_FUZZ_IDVAL == LE_ID_MIME
    183 /* libmagic sniffs everything; no useful magic of our own */
    184 #define LE_FUZZ_MAGIC ""
    185 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    186 
    187 #elif LE_FUZZ_IDVAL == LE_ID_THUMBNAILFFMPEG
    188 /* Ogg, which is what the media plugins are tested against; libmagic has
    189    to recognize it as video/* or the plugin declines to look at all */
    190 #define LE_FUZZ_MAGIC "OggS\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00"
    191 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    192 
    193 #elif LE_FUZZ_IDVAL == LE_ID_PECOFF
    194 /* MZ header; the PE header offset lives at 0x3c */
    195 /* carries a valid e_lfanew at 0x3c pointing at the "PE\0\0" signature;
    196    without it every generated input dies at the second check */
    197 #define LE_FUZZ_MAGIC \
    198         "\x4d\x5a" \
    199         "\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" \
    200         "\x40\x00\x00\x00\x50\x45\x00\x00"
    201 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    202 
    203 #elif LE_FUZZ_IDVAL == LE_ID_LNK
    204 /* header size 0x4c followed by the shell link CLSID */
    205 #define LE_FUZZ_MAGIC \
    206         "\x4c\x00\x00\x00\x01\x14\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46"
    207 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    208 
    209 #elif LE_FUZZ_IDVAL == LE_ID_SQLITE
    210 /* the header is the first 100 bytes */
    211 #define LE_FUZZ_MAGIC "SQLite format 3\x00"
    212 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    213 
    214 #elif LE_FUZZ_IDVAL == LE_ID_TAR
    215 /* the ustar magic is at offset 257, so the prefix only seeds the name field */
    216 #define LE_FUZZ_MAGIC "testfile\x00"
    217 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    218 
    219 #elif LE_FUZZ_IDVAL == LE_ID_ISO9660
    220 /* the primary volume descriptor is at offset 32768, out of reach of a prefix */
    221 #define LE_FUZZ_MAGIC "\x01" "CD001"
    222 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    223 
    224 #elif LE_FUZZ_IDVAL == LE_ID_DISKIMAGE
    225 /* qcow2; the VMDK/VHD/VHDX branches are reached from the corpus */
    226 #define LE_FUZZ_MAGIC "QFI\xfb\x00\x00\x00\x03"
    227 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    228 
    229 #elif LE_FUZZ_IDVAL == LE_ID_HEIF
    230 /* ISO base media file format: big-endian length-prefixed boxes */
    231 #define LE_FUZZ_MAGIC "\x00\x00\x00\x18" "ftypheic\x00\x00\x00\x00mif1heic"
    232 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE
    233 
    234 #elif LE_FUZZ_IDVAL == LE_ID_WEBP
    235 /* RIFF: little-endian length-prefixed chunks */
    236 #define LE_FUZZ_MAGIC "RIFF\x00\x00\x00\x00WEBPVP8X"
    237 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_LE
    238 
    239 #elif LE_FUZZ_IDVAL == LE_ID_PLIST
    240 /* the trailer is the last 32 bytes */
    241 #define LE_FUZZ_MAGIC "bplist00"
    242 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    243 
    244 #elif LE_FUZZ_IDVAL == LE_ID_ID3
    245 /* ID3v2 header with a synchsafe size */
    246 #define LE_FUZZ_MAGIC "ID3\x03\x00\x00\x00\x00\x00\x00"
    247 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    248 
    249 #elif LE_FUZZ_IDVAL == LE_ID_GPX
    250 #define LE_FUZZ_MAGIC \
    251         "<?xml version=\"1.0\"?>\n<gpx version=\"1.1\" creator=\"x\">"
    252 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT
    253 
    254 #elif LE_FUZZ_IDVAL == LE_ID_KML
    255 #define LE_FUZZ_MAGIC \
    256         "<?xml version=\"1.0\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\">"
    257 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT
    258 
    259 #elif LE_FUZZ_IDVAL == LE_ID_GEOTIFF
    260 /* little-endian classic TIFF; the geo tags live in the IFD */
    261 #define LE_FUZZ_MAGIC "II\x2a\x00\x08\x00\x00\x00"
    262 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    263 
    264 #elif LE_FUZZ_IDVAL == LE_ID_MBOX
    265 /* the envelope line alone is rejected: the plugin also requires a
    266    well-formed header block behind it */
    267 #define LE_FUZZ_MAGIC \
    268         "From a@b Mon Jan  1 00:00:00 2024\n" \
    269         "From: a@b\nDate: 1 Jan 2024 00:00:00 +0000\n"
    270 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT
    271 
    272 #elif LE_FUZZ_IDVAL == LE_ID_APK
    273 /* LE_SHAPE_ZIP synthesises the whole container, so a magic prefix
    274    would sit in front of it and invalidate every local header
    275    offset; the zip harness leaves it empty for the same reason */
    276 #define LE_FUZZ_MAGIC ""
    277 #define LE_FUZZ_SHAPE LE_SHAPE_ZIP
    278 
    279 #elif LE_FUZZ_IDVAL == LE_ID_EBOOK
    280 /* EPUB; the MOBI branch has its "BOOKMOBI" magic at offset 60 and
    281    cannot be expressed as a prefix, so seed the corpus with
    282    testdata/ebook_test.mobi to reach it */
    283 #define LE_FUZZ_MAGIC ""
    284 #define LE_FUZZ_SHAPE LE_SHAPE_ZIP
    285 
    286 #elif LE_FUZZ_IDVAL == LE_ID_PREVIEWOPUS
    287 #define LE_FUZZ_MAGIC "OggS\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00"
    288 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    289 
    290 #elif LE_FUZZ_IDVAL == LE_ID_MPEG
    291 #define LE_FUZZ_MAGIC "\x00\x00\x01\xba"
    292 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    293 
    294 #elif LE_FUZZ_IDVAL == LE_ID_MSOFFICE
    295 /* OOXML is a ZIP */
    296 #define LE_FUZZ_MAGIC ""
    297 #define LE_FUZZ_SHAPE LE_SHAPE_ZIP
    298 
    299 #elif LE_FUZZ_IDVAL == LE_ID_NSF
    300 #define LE_FUZZ_MAGIC "NESM\x1a\x01"
    301 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    302 
    303 #elif LE_FUZZ_IDVAL == LE_ID_NSFE
    304 #define LE_FUZZ_MAGIC "NSFE"
    305 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE
    306 
    307 #elif LE_FUZZ_IDVAL == LE_ID_ODF
    308 #define LE_FUZZ_MAGIC ""
    309 #define LE_FUZZ_SHAPE LE_SHAPE_ZIP
    310 
    311 #elif LE_FUZZ_IDVAL == LE_ID_OGG
    312 #define LE_FUZZ_MAGIC "OggS\x00\x02"
    313 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    314 
    315 #elif LE_FUZZ_IDVAL == LE_ID_OLE2
    316 #define LE_FUZZ_MAGIC "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1"
    317 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    318 
    319 #elif LE_FUZZ_IDVAL == LE_ID_PNG
    320 #define LE_FUZZ_MAGIC "\x89PNG\r\n\x1a\n"
    321 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE
    322 
    323 #elif LE_FUZZ_IDVAL == LE_ID_PS
    324 #define LE_FUZZ_MAGIC "%!PS-Adobe-3.0\n"
    325 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT
    326 
    327 #elif LE_FUZZ_IDVAL == LE_ID_QT
    328 /* QuickTime: size + 'moov' at the very start is the easy way in */
    329 #define LE_FUZZ_MAGIC "\x00\x00\x00\x08moov"
    330 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE
    331 
    332 #elif LE_FUZZ_IDVAL == LE_ID_REAL
    333 #define LE_FUZZ_MAGIC ".RMF\x00\x00\x00\x12"
    334 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_BE
    335 
    336 #elif LE_FUZZ_IDVAL == LE_ID_RIFF
    337 #define LE_FUZZ_MAGIC "RIFF"
    338 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_LE
    339 
    340 #elif LE_FUZZ_IDVAL == LE_ID_RTF
    341 #define LE_FUZZ_MAGIC "{\\rtf1"
    342 #define LE_FUZZ_SHAPE LE_SHAPE_TEXT
    343 
    344 #elif LE_FUZZ_IDVAL == LE_ID_S3M
    345 /* the 'SCRM' tag lives at offset 0x2c, so the magic here is the whole
    346    leading header up to and including it */
    347 #define LE_FUZZ_MAGIC \
    348         "fuzz s3m module\x00" "\x1a\x10\x00\x00" \
    349         "\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
    350         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "SCRM"
    351 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    352 
    353 #elif LE_FUZZ_IDVAL == LE_ID_SID
    354 #define LE_FUZZ_MAGIC "PSID\x00\x02\x00\x7c\x00\x7c"
    355 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    356 
    357 #elif LE_FUZZ_IDVAL == LE_ID_TIFF
    358 #define LE_FUZZ_MAGIC "II\x2a\x00\x08\x00\x00\x00"
    359 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    360 
    361 #elif LE_FUZZ_IDVAL == LE_ID_WAV
    362 #define LE_FUZZ_MAGIC "RIFF"
    363 #define LE_FUZZ_SHAPE LE_SHAPE_CHUNK_LE
    364 
    365 #elif LE_FUZZ_IDVAL == LE_ID_XM
    366 #define LE_FUZZ_MAGIC "Extended Module: "
    367 #define LE_FUZZ_SHAPE LE_SHAPE_RAW
    368 
    369 #elif LE_FUZZ_IDVAL == LE_ID_ZIP
    370 #define LE_FUZZ_MAGIC ""
    371 #define LE_FUZZ_SHAPE LE_SHAPE_ZIP
    372 
    373 #else
    374 #error "no format description for this LE_FUZZ_ID; add one above"
    375 #endif
    376 
    377 #endif /* LE_FUZZ_PLUGIN_NAME_H */