File 6576-inet_dns-FORMERR-if-more-than-one-EDNS-0-option-is-p.patch of Package erlang

From 09a202f9624bc76bc2645da5dac9028a56fc544f Mon Sep 17 00:00:00 2001
From: Alexander Clouter <alex@digriz.org.uk>
Date: Thu, 2 Mar 2023 20:05:47 +0000
Subject: [PATCH 06/10] inet_dns: FORMERR if more than one EDNS(0) option is
 present

---
 lib/kernel/src/inet_dns.erl        |  3 +++
 lib/kernel/test/inet_res_SUITE.erl | 15 +++++++++++++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/lib/kernel/src/inet_dns.erl b/lib/kernel/src/inet_dns.erl
index 4da73f0cc9..9031b0b91f 100644
--- a/lib/kernel/src/inet_dns.erl
+++ b/lib/kernel/src/inet_dns.erl
@@ -236,6 +236,9 @@ decode_rr_section(Bin, N, Buffer, RRs) ->
            RR =
                case Type of
                    ?S_OPT ->
+                       %% RFC 6891: 6.1.1. FORMERR if more than one dns_rr_opt
+                       lists:keymember(dns_rr_opt, 1, RRs) andalso
+                        throw(?DECODE_ERROR),
                        <<ExtRcode,Version,DO:1,Z:15>> = TTL,
                        DnssecOk = (DO =/= 0),
                        #dns_rr_opt{
diff --git a/lib/kernel/test/inet_res_SUITE.erl b/lib/kernel/test/inet_res_SUITE.erl
index 062857ee92..c620e6d93e 100644
--- a/lib/kernel/test/inet_res_SUITE.erl
+++ b/lib/kernel/test/inet_res_SUITE.erl
@@ -32,7 +32,7 @@
 	 init_per_testcase/2, end_per_testcase/2
         ]).
 -export([basic/1, name_addr_and_cached/1, resolve/1,
-         edns0/1, txt_record/1, files_monitor/1,
+         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
@@ -73,7 +73,7 @@ suite() ->
 
 all() -> 
     [basic, resolve, name_addr_and_cached,
-     edns0, txt_record, files_monitor,
+     edns0, edns0_multi_formerr, txt_record, files_monitor,
      nxdomain_reply, last_ms_answer,
      intermediate_error,
      servfail_retry_timeout_default, servfail_retry_timeout_1000,
@@ -129,6 +129,7 @@ zone_dir(TC) ->
 	name_addr_and_cached -> otptest;
 	resolve              -> otptest;
 	edns0                -> otptest;
+	edns0_multi_formerr  -> otptest;
 	files_monitor        -> otptest;
 	nxdomain_reply       -> otptest;
 	last_ms_answer       -> otptest;
@@ -1114,6 +1115,16 @@ inet_res_filter(Anlist, Class, Type) ->
 			      inet_dns:rr(RR, type) =:= Type,
 			      inet_dns:rr(RR, class) =:= Class].
 
+%% Test EDNS we catch multiple dns_opt_rr as FORMERR (RFC 6891: 6.1.1)
+edns0_multi_formerr(Config) when is_list(Config) ->
+    Domain = "otptest",
+    Opts = [{nameservers,[ns(Config)]},{edns,0}],
+    {ok,DnsRec0} = inet_res:resolve(Domain, in, soa, Opts),
+    [EDNS|_] = [ X || X <- DnsRec0#dns_rec.arlist, is_record(X, dns_rr_opt) ],
+    DnsRec = DnsRec0#dns_rec{ arlist = [EDNS|DnsRec0#dns_rec.arlist] },
+    {error,formerr} = inet_dns:decode(inet_dns:encode(DnsRec)),
+    ok.
+
 
 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-- 
2.35.3

openSUSE Build Service is sponsored by