File 9383-inet_dns_tsig-Test-that-a-request-TSIG-RR-with-Error.patch of Package erlang

From b1415fc8f70a1c25d18d66a2441ffb30ebc97506 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Tue, 3 Mar 2026 18:16:55 +0100
Subject: [PATCH 3/3] inet_dns_tsig: Test that a request TSIG RR with Error
 does not bypass verification

Without this check, a server that uses inet_dns_tsig:verify/3
and got a request containing an illegal TSIG record, with
the 'error' field set to ?BADSIG or ?BADKEY, would
misinterpret the request as an error reply and use an
empty MAC when validating the request.  And an empty
MAC could also be in the bogus request.

All that had to be correct in such a malicious request is the
TSIG key name, which often can be guessed.

By this an attacker could manage to do an unauthorized
zone transfer that exposes internal DNS data, or do
unauthorized dynamic updates to manipulate records,
redirect traffic, or disrupt services, etc...
---
 lib/kernel/test/inet_res_SUITE.erl | 38 +++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/lib/kernel/test/inet_res_SUITE.erl b/lib/kernel/test/inet_res_SUITE.erl
index a08e255fe5..569923504e 100644
--- a/lib/kernel/test/inet_res_SUITE.erl
+++ b/lib/kernel/test/inet_res_SUITE.erl
@@ -37,7 +37,8 @@
          edns0/1, edns0_multi_formerr/1, txt_record/1, files_monitor/1,
 	 nxdomain_reply/1, last_ms_answer/1, intermediate_error/1,
          servfail_retry_timeout_default/1, servfail_retry_timeout_1000/1,
-         label_compression_limit/1, update/1, tsig_client/1, tsig_server/1,
+         label_compression_limit/1, update/1,
+         tsig_client/1, tsig_server/1, tsig_baderror/1,
          mdns_encode_decode/1
         ]).
 -export([
@@ -80,7 +81,8 @@ all() ->
      nxdomain_reply, last_ms_answer,
      intermediate_error,
      servfail_retry_timeout_default, servfail_retry_timeout_1000,
-     label_compression_limit, update, tsig_client, tsig_server,
+     label_compression_limit, update,
+     tsig_client, tsig_server, tsig_baderror,
      mdns_encode_decode,
      gethostbyaddr, gethostbyaddr_v6, gethostbyname,
      gethostbyname_v6, getaddr, getaddr_v6, ipv4_to_ipv6,
@@ -1715,6 +1717,36 @@ tsig_server(Domain, TS0, Sock) ->
     ok = gen_tcp:send(Sock, PktR3S).
 
 
+tsig_baderror(Config) when is_list(Config) ->
+    do_tsig_baderror(?BADSIG),
+    do_tsig_baderror(?BADKEY),
+    ok.
+
+do_tsig_baderror(Error) ->
+    Domain = "otptest",
+    Key = {"testkey","b0b8006a-04ad-4a96-841a-a4eae78011a1"},
+    Keys0 = [Key,{"grease0",""},{"grease1",""},{"grease2",""}],
+    Rand = [ rand:uniform() || _ <- lists:seq(1, length(Keys0)) ],
+    {_,Keys} = lists:unzip(lists:keysort(1, lists:zip(Rand, Keys0))),
+    TS = inet_dns_tsig:init([{keys,Keys}]),
+    %%
+    Algname = inet_dns:encode_algname(sha256),
+    Now = os:system_time(seconds),
+    Request =
+        #dns_rec{
+           header = #dns_header{},
+           qdlist = [#dns_query{ domain = Domain, class = in, type = axfr }],
+           arlist =
+               [#dns_rr_tsig{
+                   domain = "testkey",
+                   algname = Algname, now = Now, fudge = 300,
+                   error = Error, mac = <<>> }]
+          },
+    Pkt = inet_dns:encode(Request),
+    {ok, Msg} = inet_dns:decode(Pkt),
+    {error, formerr} = inet_dns_tsig:verify(Pkt, Msg, TS),
+    ok.
+
 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% inet_dns encode/decode specials
 %% Should maybe be a suite of its own.
-- 
2.51.0

openSUSE Build Service is sponsored by