- Fix validator to set unchecked when validation recursion

requests are passed. The edns subnet module checks if validation
  is needed for a cache response, and set the validator to protect
  the cache with validation for non-subnet lookups.
This commit is contained in:
W.C.A. Wijngaards
2026-02-25 10:59:33 +01:00
parent fb322f3e87
commit bff3d762ff
4 changed files with 297 additions and 3 deletions
+6
View File
@@ -1,3 +1,9 @@
25 February 2026: Wouter
- Fix validator to set unchecked when validation recursion
requests are passed. The edns subnet module checks if validation
is needed for a cache response, and set the validator to protect
the cache with validation for non-subnet lookups.
23 February 2026: Wouter
- Fix to have cachedb not return expired bogus data as non-bogus.
- Fix to make the cachedb_val_expired.crpl succeed.
+14 -2
View File
@@ -483,6 +483,8 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq,
struct addrtree *tree;
struct addrnode *node;
uint8_t scope;
int must_validate = (!(qstate->query_flags&BIT_CD)
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
memset(&sq->ecs_client_out, 0, sizeof(sq->ecs_client_out));
@@ -515,7 +517,14 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq,
if (!qstate->return_msg) { /* Failed allocation or expired TTL */
return 0;
}
if(qstate->return_msg->rep->security == sec_status_unchecked
&& must_validate) {
/* The message has to be validated first. */
verbose(VERB_ALGO, "subnet: unchecked cache entry needs "
"validation");
return 0;
}
if (sq->subnet_downstream) { /* relay to interested client */
sq->ecs_client_out.subnet_scope_mask = scope;
sq->ecs_client_out.subnet_addr_fam = ecs->subnet_addr_fam;
@@ -570,7 +579,10 @@ generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate*
qflags |= BIT_RD;
if((qstate->query_flags & BIT_CD)!=0) {
qflags |= BIT_CD;
valrec = 1;
/* The valrec is left off. Leave out: valrec = 1;
* So that the cache is protected with DNSSEC validation.
* Just like the global cache. DNSSEC validation is performed
* regardless of the setting of the querier's CD flag. */
}
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
+274
View File
@@ -0,0 +1,274 @@
; Test subnet option
server:
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
val-override-date: "20070916134226"
trust-anchor-signaling: no
target-fetch-policy: "0 0 0 0 0"
send-client-subnet: 1.2.3.4
max-client-subnet-ipv4: 17
module-config: "subnetcache validator iterator"
verbosity: 3
fake-sha1: yes
fake-dsa: yes
qname-minimisation: no
minimal-responses: yes
iter-scrub-promiscuous: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test subnet with scopezero bogus response
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
ENTRY_END
; no data for ns.example.com. AAAA
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. IN SOA a. b. 3 28800 7200 604800 3600
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. ACYHmWSLfBwPXwjI23+PW0db/DuqFwgpJYCbHOPeftbLR9nGy3nyEAE=
ns.example.com. 3600 IN NSEC op.example.com. A RRSIG NSEC
ns.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AHMBw+lDAm9o2xG7v/8oWkYUc3WefUOuHFMHN9qZEp5/kooJqmlj974=
ENTRY_END
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
; to make it bogus, the address is changed.
; and also the RRSIG is expired (dated in 2005).
;www.example.com. IN A 10.20.30.40
;www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
www.example.com. IN A 10.20.30.41
www.example.com. 3600 IN RRSIG A 3 3 3600 20050926134150 20050829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; client is 127.0.0.1
00 08 ; OPC
00 07 ; option length
00 01 ; Family
11 00 ; source mask, scopemask
7f 00 00 ; address
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
; response to query of interest without subnet
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
; to make it bogus, the address is changed.
; and also the RRSIG is expired (dated in 2005).
;www.example.com. IN A 10.20.30.40
;www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
www.example.com. IN A 10.20.30.41
www.example.com. 3600 IN RRSIG A 3 3 3600 20050926134150 20050829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
RANGE_END
; query for www.example.com 0.0.0.0/0 with CD flag
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD CD DO NOERROR
SECTION QUESTION
www.example.com. IN A
HEX_EDNSDATA_BEGIN
; 0.0.0.0/0 scope /0
00 08 ; OPC
00 04 ; option length
00 01 ; Family
00 00 ; source mask, scopemask
; address
HEX_EDNSDATA_END
ENTRY_END
; recursion happens here.
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ednsdata
REPLY QR RD CD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.41
www.example.com. 3600 IN RRSIG A 3 3 3600 20050926134150 20050829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; 0.0.0.0/0 scope /0
00 08 ; OPC
00 04 ; option length
00 01 ; Family
00 00 ; source mask, scopemask
; address
HEX_EDNSDATA_END
ENTRY_END
; query for www.example.com 0.0.0.0/0 without CD flag
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD DO NOERROR
SECTION QUESTION
www.example.com. IN A
HEX_EDNSDATA_BEGIN
; 0.0.0.0/0 scope /0
00 08 ; OPC
00 04 ; option length
00 01 ; Family
00 00 ; source mask, scopemask
; address
HEX_EDNSDATA_END
ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ednsdata
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; ; 0.0.0.0/0 scope /0
; 00 08 ; OPC
; 00 04 ; option length
; 00 01 ; Family
; 00 00 ; source mask, scopemask
; ; address
HEX_EDNSDATA_END
ENTRY_END
SCENARIO_END
+3 -1
View File
@@ -2699,7 +2699,9 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id,
if(!needs_validation(qstate, qstate->return_rcode,
qstate->return_msg)) {
/* no need to validate this */
if(qstate->return_msg)
/* For valrec responses, leave at sec_status_unchecked,
* no security status has been requested for it. */
if(qstate->return_msg && !qstate->is_valrec)
qstate->return_msg->rep->security =
sec_status_indeterminate;
qstate->ext_state[id] = module_finished;