GNU libmicrohttpd 1.0.9
Loading...
Searching...
No Matches
fuzz_str.c File Reference

Direct in-process fuzzer for the string primitives of mhd_str.c. More...

#include "fuzz_common.h"
#include "mhd_options.h"
#include "mhd_str.h"
Include dependency graph for fuzz_str.c:

Go to the source code of this file.

Macros

#define FUZZ_HARNESS_NAME   "fuzz_str"
 
#define MODEL_MAX_DIGEST   32
 
#define SSEED(t)
 

Enumerations

enum  str_target {
  TGT_HEX_TO_BIN = 0 , TGT_BIN_TO_HEX , TGT_BIN_TO_HEX_Z , TGT_PCT_STRICT ,
  TGT_PCT_LENIENT , TGT_PCT_IN_PLACE_STRICT , TGT_PCT_IN_PLACE_LENIENT , TGT_UNQUOTE ,
  TGT_QUOTE , TGT_BASE64 , TGT_TO_UINT64 , TGT_TOKENS ,
  TGT_EQUAL_CASELESS , TGT_DIGEST_HEX_SINK , TGT_COUNT
}
 

Functions

static void * xalloc (size_t n)
 
static char * dup_z (const uint8_t *d, size_t n)
 
int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
 
static size_t fuzz_generate (struct fuzz_rng *rng, uint8_t *buf, size_t cap)
 
static size_t fuzz_seed_count (void)
 
static const uint8_t * fuzz_seed_get (size_t idx, size_t *len)
 

Variables

static int model_digest_sink
 
static int model_digest_sink_read
 
static const char *const gen_str_atoms []
 
static const struct str_seed str_seeds []
 

Detailed Description

Direct in-process fuzzer for the string primitives of mhd_str.c.

Author
Christian Grothoff

Every destination buffer is obtained with malloc() at exactly the size that the documented contract of the function under test requires – never a generous stack array. Under AddressSanitizer the redzone immediately after the allocation turns any one-byte over-write into a hard error, which is precisely the property a fixed-size stack buffer would not give us.

In addition to the contract-exact calls, several functions are also called with a deliberately too small output buffer: functions that take a buffer size argument must detect this and must not write past the end.

Input format: byte 0 target selector byte 1 auxiliary parameter (buffer size shrink, split point, ...) byte 2.. payload

Definition in file fuzz_str.c.

Macro Definition Documentation

◆ FUZZ_HARNESS_NAME

#define FUZZ_HARNESS_NAME   "fuzz_str"

Definition at line 43 of file fuzz_str.c.

◆ MODEL_MAX_DIGEST

#define MODEL_MAX_DIGEST   32

Largest digest MHD supports; this is the size of the on-stack buffers that digestauth.c passes to MHD_hex_to_bin().

Definition at line 53 of file fuzz_str.c.

Referenced by LLVMFuzzerTestOneInput().

◆ SSEED

#define SSEED ( t)
Value:
{ t, sizeof (t) - 1 }

Definition at line 500 of file fuzz_str.c.

Enumeration Type Documentation

◆ str_target

enum str_target
Enumerator
TGT_HEX_TO_BIN 
TGT_BIN_TO_HEX 
TGT_BIN_TO_HEX_Z 
TGT_PCT_STRICT 
TGT_PCT_LENIENT 
TGT_PCT_IN_PLACE_STRICT 
TGT_PCT_IN_PLACE_LENIENT 
TGT_UNQUOTE 
TGT_QUOTE 
TGT_BASE64 
TGT_TO_UINT64 
TGT_TOKENS 
TGT_EQUAL_CASELESS 
TGT_DIGEST_HEX_SINK 
TGT_COUNT 

Definition at line 70 of file fuzz_str.c.

Function Documentation

◆ dup_z()

static char * dup_z ( const uint8_t * d,
size_t n )
static

Definition at line 107 of file fuzz_str.c.

References xalloc().

Referenced by LLVMFuzzerTestOneInput().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fuzz_generate()

static size_t fuzz_generate ( struct fuzz_rng * rng,
uint8_t * buf,
size_t cap )
static

Definition at line 442 of file fuzz_str.c.

References fuzz_below(), fuzz_byte(), fuzz_chance(), gen_str_atoms, and TGT_COUNT.

Here is the call graph for this function:

◆ fuzz_seed_count()

static size_t fuzz_seed_count ( void )
static

Definition at line 532 of file fuzz_str.c.

References str_seeds.

◆ fuzz_seed_get()

static const uint8_t * fuzz_seed_get ( size_t idx,
size_t * len )
static

Definition at line 539 of file fuzz_str.c.

References str_seeds.

◆ LLVMFuzzerTestOneInput()

◆ xalloc()

static void * xalloc ( size_t n)
static

Allocate exactly n bytes. Zero-sized allocations are turned into a one byte allocation so that the returned pointer stays valid, but the harness never tells the library about that extra byte.

Definition at line 96 of file fuzz_str.c.

References NULL.

Referenced by dup_z(), and LLVMFuzzerTestOneInput().

Here is the caller graph for this function:

Variable Documentation

◆ gen_str_atoms

const char* const gen_str_atoms[]
static
Initial value:
= {
"%41", "%", "%%", "%zz", "%0", "%00", "%ff", "\\", "\\\"", "\"",
"0123456789abcdef", "0123456789ABCDEF", "ffffffffffffffffffffffff",
"gg", "0x", "18446744073709551615", "99999999999999999999",
"a, b, c", "chunked", "identity", " , ", ",,", "token",
"QUJD", "QQ==", "Q===", "====", "AAAA", "AA=A",
"\x00\x01\x7f\x80\xff", " ", "\t", "\r\n"
}

Definition at line 431 of file fuzz_str.c.

Referenced by fuzz_generate().

◆ model_digest_sink

int model_digest_sink
static

Model the (pre-2026) digestauth.c call site that fed a client controlled, up to 4 * digest_size characters long 'response' value into MHD_hex_to_bin() together with a digest_size byte buffer.

MHD_hex_to_bin() has no output size parameter: it writes len/2 bytes, so a caller with a fixed size buffer must bound the input length. This target replays that call site with an exactly sized heap buffer so that ASAN reports the overflow. It is OFF by default (it models a caller, not the library) – enable it with MHD_FUZZ_MODEL_DIGEST_SINK=1 to reproduce the primitive behind the digest 'response' overflow.

Definition at line 67 of file fuzz_str.c.

Referenced by LLVMFuzzerTestOneInput().

◆ model_digest_sink_read

int model_digest_sink_read
static

Definition at line 68 of file fuzz_str.c.

Referenced by LLVMFuzzerTestOneInput().

◆ str_seeds

const struct str_seed str_seeds[]
static
Initial value:
= {
SSEED ("\x00\x00"
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"),
SSEED ("\x00\x00" "0123456789abcdef0123456789abcdef"),
SSEED ("\x00\x00" "abc"),
SSEED ("\x00\x00" "zz"),
SSEED ("\x01\x00" "\x01\x02\x03\x04"),
SSEED ("\x02\x00" "\xff\xfe"),
SSEED ("\x03\x00" "/a%41%42%zz%"),
SSEED ("\x04\x40" "/a%41%42%zz%"),
SSEED ("\x05\x00" "%41%42%%%0"),
SSEED ("\x06\x00" "%41%42%%%0"),
SSEED ("\x07\x00" "a\\\"b\\\\c"),
SSEED ("\x08\x00" "a\"b\\c"),
SSEED ("\x09\x00" "QUJDRA=="),
SSEED ("\x09\x00" "QUJDR==="),
SSEED ("\x0a\x00" "18446744073709551615"),
SSEED ("\x0a\x00" "ffffffffffffffff"),
SSEED ("\x0b\x03" "chunked, identity, chunked"),
SSEED ("\x0c\x04" "CHUNKEDchunked"),
SSEED ("\x0d\x00"
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
}
#define SSEED(t)
Definition fuzz_str.c:500

Definition at line 502 of file fuzz_str.c.

Referenced by fuzz_seed_count(), and fuzz_seed_get().