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

Direct fuzzer for the "Authorization:" header parsers. More...

#include "fuzz_common.h"
#include "internal.h"
#include "memorypool.h"
#include "gen_auth.h"
#include "mhd_str.h"
Include dependency graph for fuzz_auth_header.c:

Go to the source code of this file.

Macros

#define FUZZ_HARNESS_NAME   "fuzz_auth_header"
 
#define ADD(s)
 
#define ASEED(t)
 

Functions

static char * fuzz_dup_n (const char *src, size_t len)
 
static void print_stats (void)
 
static enum MHD_Result dummy_ahc (void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **req_cls)
 
static void stop_shared_daemon (void)
 
static struct MHD_Daemonget_shared_daemon (void)
 
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 const size_t pool_sizes [] = { 256, 512, 1024, 4096, 32768 }
 
static struct MHD_Daemonshared_daemon
 
static unsigned long stat_dauth_parsed
 
static unsigned long stat_dauth_failed
 
static unsigned long stat_bauth_parsed
 
static unsigned long stat_bauth_failed
 
static const char *const gen_param_names []
 
static const char *const gen_param_values []
 
static const struct ah_seed ah_seeds []
 

Detailed Description

Direct fuzzer for the "Authorization:" header parsers.

Author
Christian Grothoff

MHD_get_rq_dauth_params_() and MHD_get_rq_bauth_params_() are internal (they live in gen_auth.c and are not exported), and both need a struct MHD_Connection. Rather than pushing bytes through a socket, this harness assembles the minimal connection object those two functions actually touch – a daemon pointer, a memory pool, a state and a single "Authorization" header – and then varies only the header value. That makes this the fastest way to explore the parameter parser (roughly two orders of magnitude more executions per second than fuzz_request).

Besides memory-safety (ASAN), the harness checks the parser output for internal consistency: every returned parameter must be a sub-range of the header value that was fed in. A parameter pointing outside of it would be a parser bug that ASAN alone might not catch.

Input format: byte 0 scheme selector / pool size selector byte 1.. the raw "Authorization" header value

Definition in file fuzz_auth_header.c.

Macro Definition Documentation

◆ ADD

#define ADD ( s)
Value:
do { \
const char *s_ = (s); \
size_t l_ = strlen (s_); \
if (len + l_ >= cap) \
return len; \
memcpy (buf + len, s_, l_); \
len += l_; \
} while (0)

Referenced by fuzz_generate().

◆ ASEED

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

Definition at line 502 of file fuzz_auth_header.c.

◆ FUZZ_HARNESS_NAME

#define FUZZ_HARNESS_NAME   "fuzz_auth_header"

Definition at line 45 of file fuzz_auth_header.c.

Referenced by print_stats().

Function Documentation

◆ dummy_ahc()

static enum MHD_Result dummy_ahc ( void * cls,
struct MHD_Connection * connection,
const char * url,
const char * method,
const char * version,
const char * upload_data,
size_t * upload_data_size,
void ** req_cls )
static

Definition at line 115 of file fuzz_auth_header.c.

References MHD_NO.

Referenced by get_shared_daemon().

Here is the caller graph for this function:

◆ fuzz_dup_n()

static char * fuzz_dup_n ( const char * src,
size_t len )
static

Exactly-sized, NUL terminated copy of len bytes of src.

"Exactly sized" is the point: the allocation is len + 1 bytes and not one byte more, so ASAN's redzone sits immediately behind the terminator and any read past it is reported.

Definition at line 73 of file fuzz_auth_header.c.

References NULL.

Referenced by LLVMFuzzerTestOneInput().

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 433 of file fuzz_auth_header.c.

References ADD, fuzz_below(), fuzz_byte(), fuzz_chance(), gen_param_names, and gen_param_values.

Here is the call graph for this function:

◆ fuzz_seed_count()

static size_t fuzz_seed_count ( void )
static

Definition at line 550 of file fuzz_auth_header.c.

References ah_seeds.

◆ fuzz_seed_get()

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

Definition at line 557 of file fuzz_auth_header.c.

References ah_seeds.

◆ get_shared_daemon()

static struct MHD_Daemon * get_shared_daemon ( void )
static

Definition at line 142 of file fuzz_auth_header.c.

References dummy_ahc(), fuzz_verbose, MHD_OPTION_END, MHD_start_daemon(), MHD_USE_ERROR_LOG, MHD_USE_NO_LISTEN_SOCKET, NULL, print_stats(), shared_daemon, and stop_shared_daemon().

Referenced by LLVMFuzzerTestOneInput().

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

◆ LLVMFuzzerTestOneInput()

◆ print_stats()

static void print_stats ( void )
static

Definition at line 101 of file fuzz_auth_header.c.

References FUZZ_HARNESS_NAME, fuzz_verbose, stat_bauth_failed, stat_bauth_parsed, stat_dauth_failed, and stat_dauth_parsed.

Referenced by get_shared_daemon().

Here is the caller graph for this function:

◆ stop_shared_daemon()

static void stop_shared_daemon ( void )
static

Definition at line 131 of file fuzz_auth_header.c.

References MHD_stop_daemon(), NULL, and shared_daemon.

Referenced by get_shared_daemon().

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

Variable Documentation

◆ ah_seeds

const struct ah_seed ah_seeds[]
static

Definition at line 504 of file fuzz_auth_header.c.

Referenced by fuzz_seed_count(), and fuzz_seed_get().

◆ gen_param_names

const char* const gen_param_names[]
static
Initial value:
= {
"username", "username*", "realm", "nonce", "uri", "response", "algorithm",
"qop", "nc", "cnonce", "opaque", "userhash", "charset", "domain",
"unknown", "", "USERNAME", "user name"
}

Definition at line 413 of file fuzz_auth_header.c.

Referenced by fuzz_generate().

◆ gen_param_values

const char* const gen_param_values[]
static
Initial value:
= {
"\"user\"", "user", "\"\"", "\"a\\\"b\"", "\"a\\\\\"", "\"\\\"",
"UTF-8''a%20b", "utf-8''%41", "''", "'", "true", "false", "TRUE",
"auth", "auth-int", "auth,auth-int", "\"auth\"", "MD5", "SHA-256",
"SHA-512-256", "BOGUS", "\"SHA-256\"", "00000001", "ffffffff",
"0123456789abcdef0123456789abcdef",
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\""
}

Definition at line 419 of file fuzz_auth_header.c.

Referenced by fuzz_generate().

◆ pool_sizes

const size_t pool_sizes[] = { 256, 512, 1024, 4096, 32768 }
static

Definition at line 62 of file fuzz_auth_header.c.

Referenced by LLVMFuzzerTestOneInput().

◆ shared_daemon

struct MHD_Daemon* shared_daemon
static

gen_auth.c logs through MHD_DLOG(), which dereferences the daemon of the connection, so a real (but idle) daemon is required. It is created once and reused for the whole run.

Definition at line 91 of file fuzz_auth_header.c.

Referenced by get_shared_daemon(), LLVMFuzzerTestOneInput(), and stop_shared_daemon().

◆ stat_bauth_failed

unsigned long stat_bauth_failed
static

Definition at line 97 of file fuzz_auth_header.c.

Referenced by LLVMFuzzerTestOneInput(), and print_stats().

◆ stat_bauth_parsed

unsigned long stat_bauth_parsed
static

Definition at line 96 of file fuzz_auth_header.c.

Referenced by LLVMFuzzerTestOneInput(), and print_stats().

◆ stat_dauth_failed

unsigned long stat_dauth_failed
static

Definition at line 95 of file fuzz_auth_header.c.

Referenced by LLVMFuzzerTestOneInput(), and print_stats().

◆ stat_dauth_parsed

unsigned long stat_dauth_parsed
static

Statistics, printed at exit with –verbose.

Definition at line 94 of file fuzz_auth_header.c.

Referenced by LLVMFuzzerTestOneInput(), and print_stats().