From: W.C.A. Wijngaards Date: Wed, 21 May 2025 10:41:54 +0000 (+0200) Subject: - Fix #1288: [FR] Improve fuzzing of unbound by adapting the netbound X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=ff7dfd52a29416b225dda2c2e60c01f455d60049;p=thirdparty%2Funbound.git - Fix #1288: [FR] Improve fuzzing of unbound by adapting the netbound program. --- diff --git a/doc/Changelog b/doc/Changelog index 2e2f96df8..b86a04524 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +21 May 2025: Wouter + - Fix #1288: [FR] Improve fuzzing of unbound by adapting the netbound + program. + 20 May 2025: Yorgos - Merge #1285: RST man pages. It introduces restructuredText man pages to sync the online and source code man page documentation. diff --git a/testcode/fake_event.c b/testcode/fake_event.c index f7f321079..0942fcd83 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -900,8 +900,10 @@ run_scenario(struct replay_runtime* runtime) runtime->now->evt_type == repevt_front_reply) { answer_check_it(runtime); advance_moment(runtime); - } else if(pending_matches_range(runtime, &entry, &pending)) { - answer_callback_from_entry(runtime, entry, pending); + } else if(runtime->now && pending_matches_range(runtime, + &entry, &pending)) { + if(entry) + answer_callback_from_entry(runtime, entry, pending); } else { do_moment_and_advance(runtime); } @@ -1274,7 +1276,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, (flags&~(BIT_RD|BIT_CD))?" MORE":"", (dnssec)?" DO":""); /* create packet with EDNS */ - pend->buffer = sldns_buffer_new(512); + pend->buffer = sldns_buffer_new(4096); log_assert(pend->buffer); sldns_buffer_write_u16(pend->buffer, 0); /* id */ sldns_buffer_write_u16(pend->buffer, flags); @@ -1334,7 +1336,13 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, edns.opt_list_in = NULL; edns.opt_list_out = per_upstream_opt_list; edns.opt_list_inplace_cb_out = NULL; - attach_edns_record(pend->buffer, &edns); + if(sldns_buffer_capacity(pend->buffer) >= + sldns_buffer_limit(pend->buffer) + +calc_edns_field_size(&edns)) { + attach_edns_record(pend->buffer, &edns); + } else { + verbose(VERB_ALGO, "edns field too large to fit"); + } } memcpy(&pend->addr, addr, addrlen); pend->addrlen = addrlen; diff --git a/testcode/replay.c b/testcode/replay.c index 95dde405f..fd946d53d 100644 --- a/testcode/replay.c +++ b/testcode/replay.c @@ -795,7 +795,7 @@ macro_expand(rbtree_type* store, struct replay_runtime* runtime, char** text) char buf[10240]; char* at = *text; size_t len = macro_length(at); - int dofunc = 0; + int tries = 0, dofunc = 0; char* arithstart = NULL; if(len >= sizeof(buf)) return NULL; /* too long */ @@ -834,6 +834,8 @@ macro_expand(rbtree_type* store, struct replay_runtime* runtime, char** text) /* actual macro text expansion */ while(*at) { size_t remain = sizeof(buf)-strlen(buf); + if(tries++ > 10000) + return NULL; /* looks like got into an infinite loop, bail out */ if(strncmp(at, "${", 2) == 0) { at = do_macro_recursion(store, runtime, at, remain); } else if(*at == '$') { diff --git a/testcode/testbound.c b/testcode/testbound.c index 67af33b61..410ec165c 100644 --- a/testcode/testbound.c +++ b/testcode/testbound.c @@ -339,6 +339,35 @@ static void remove_configfile(void) cfgfiles = NULL; } +/** perform the playback on the playback_file with the args. */ +static int +perform_playback(char* playback_file, int pass_argc, char** pass_argv) +{ + struct replay_scenario* scen = NULL; + int c, res; + + /* setup test environment */ + scen = setup_playback(playback_file, &pass_argc, pass_argv); + /* init fake event backend */ + fake_event_init(scen); + + pass_argv[pass_argc] = NULL; + echo_cmdline(pass_argc, pass_argv); + + /* run the normal daemon */ + res = daemon_main(pass_argc, pass_argv); + + fake_event_cleanup(); + for(c=1; c 0) { if(rdlen < 4) return -1; /* malformed */ optlen = sldns_read_uint16(rdata+2); + if((size_t)rdlen < 4+((size_t)optlen)) + return -1; /* malformed */ if(sldns_read_uint16(rdata) == code) { /* save data to buf for caller inspection */ memmove(buf, rdata+4, optlen); @@ -1134,8 +1138,9 @@ static void lowercase_dname(uint8_t** p, size_t* remain) while(**p != 0) { /* compressed? */ if((**p & 0xc0) == 0xc0) { - *p += 2; - *remain -= 2; + llen = *remain < 2 ? (unsigned int)*remain : 2; + *p += llen; + *remain -= llen; return; } llen = (unsigned int)**p; @@ -1178,6 +1183,12 @@ static void lowercase_rdata(uint8_t** p, size_t* remain, uint8_t len; if(rdataremain == 0) return; len = **p; + if(rdataremain < ((size_t)len)+1) { + /* malformed LDNS_RDF_TYPE_STR, skip remainder */ + *p += rdataremain; + *remain -= rdatalen; + return; + } *p += len+1; rdataremain -= len+1; } else { @@ -1207,6 +1218,12 @@ static void lowercase_rdata(uint8_t** p, size_t* remain, break; default: error("bad rdf type in lowercase %d", (int)f); } + if (rdataremain < (size_t)len) { + /* malformed RDF, skip remainder */ + *p += rdataremain; + *remain -= rdatalen; + return; + } *p += len; rdataremain -= len; } diff --git a/util/random.c b/util/random.c index 6eb102c63..92a4f6dd0 100644 --- a/util/random.c +++ b/util/random.c @@ -78,6 +78,37 @@ */ #define MAX_VALUE 0x7fffffff +/* If the build mode is for fuzzing this removes randomness from the output. + * This helps fuzz engines from having state increase due to the randomness. */ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +struct ub_randstate { + unsigned int dummy; +}; + +struct ub_randstate* ub_initstate(struct ub_randstate* ATTR_UNUSED(from)) +{ + struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s)); + if(!s) { + log_err("malloc failure in random init"); + return NULL; + } + return s; +} + +long int ub_random(struct ub_randstate* state) +{ + state->dummy++; + return (long int)(state->dummy & MAX_VALUE); +} + +long int +ub_random_max(struct ub_randstate* state, long int x) +{ + state->dummy++; + return ((long int)state->dummy % x); +} +#else /* !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + #if defined(HAVE_SSL) || defined(HAVE_LIBBSD) struct ub_randstate* ub_initstate(struct ub_randstate* ATTR_UNUSED(from)) @@ -200,6 +231,8 @@ ub_random_max(struct ub_randstate* state, long int x) } #endif /* HAVE_NSS or HAVE_NETTLE and !HAVE_LIBBSD */ +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + void ub_randfree(struct ub_randstate* s) {