diff --git a/doc/Changelog b/doc/Changelog index 818302ce7..04373cbc5 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,8 @@ +4 September 2026: Wouter + - Fix to make rpz_config leave the rpz with correct set up + on failure. The struct is not half configured on exit. + Thanks to Qifan Zhang, Palo Alto Networks, for the report. + 3 September 2026: Wouter - Fix to match NSEC3 hash length to the NSEC3 algorithm, this stops negative cache overdeletion. It also contrains diff --git a/services/rpz.c b/services/rpz.c index 1a23e52a0..64921396d 100644 --- a/services/rpz.c +++ b/services/rpz.c @@ -507,12 +507,22 @@ static int rpz_apply_cfg_elements(struct rpz* r, struct config_auth* p) { if(p->rpz_taglist && p->rpz_taglistlen) { - r->taglistlen = p->rpz_taglistlen; - r->taglist = memdup(p->rpz_taglist, r->taglistlen); - if(!r->taglist) { + uint8_t* taglist = memdup(p->rpz_taglist, p->rpz_taglistlen); + if(!taglist) { log_err("malloc failure on RPZ taglist alloc"); return 0; } + if(r->taglist) + free(r->taglist); + r->taglist = taglist; + r->taglistlen = p->rpz_taglistlen; + } else { + /* free taglist, if any */ + if(r->taglist) { + free(r->taglist); + r->taglist = NULL; + r->taglistlen = 0; + } } if(p->rpz_action_override) { @@ -524,6 +534,8 @@ rpz_apply_cfg_elements(struct rpz* r, struct config_auth* p) if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) { uint8_t nm[LDNS_MAX_DOMAINLEN+1]; size_t nmlen = sizeof(nm); + struct regional* newr; + struct ub_packed_rrset_key* cname_override; if(!p->rpz_cname) { log_err("rpz: override with cname action found, but no " @@ -536,18 +548,39 @@ rpz_apply_cfg_elements(struct rpz* r, struct config_auth* p) p->rpz_cname); return 0; } - r->cname_override = new_cname_override(r->region, nm, nmlen); - if(!r->cname_override) { + newr = regional_create_custom(sizeof(struct regional)); + if(!newr) { + log_err("malloc failure on RPZ cname override region"); return 0; } + cname_override = new_cname_override(newr, nm, nmlen); + if(!cname_override) { + regional_destroy(newr); + return 0; + } + regional_destroy(r->region); + r->region = newr; + r->cname_override = cname_override; + } else { + delete_cname_override(r); } r->log = p->rpz_log; r->signal_nxdomain_ra = p->rpz_signal_nxdomain_ra; if(p->rpz_log_name) { - if(!(r->log_name = strdup(p->rpz_log_name))) { + char* log_name = strdup(p->rpz_log_name); + if(!log_name) { log_err("malloc failure on RPZ log_name strdup"); return 0; } + if(r->log_name) + free(r->log_name); + r->log_name = log_name; + } else { + /* free logname, if any */ + if(r->log_name) { + free(r->log_name); + r->log_name = NULL; + } } return 1; } @@ -616,22 +649,6 @@ rpz_config(struct rpz* r, struct config_auth* p) { /* If the zonefile changes, it is read later, after which * rpz_clear and rpz_finish_config is called. */ - - /* free taglist, if any */ - if(r->taglist) { - free(r->taglist); - r->taglist = NULL; - r->taglistlen = 0; - } - - /* free logname, if any */ - if(r->log_name) { - free(r->log_name); - r->log_name = NULL; - } - - delete_cname_override(r); - if(!rpz_apply_cfg_elements(r, p)) return 0; return 1;