From d2faa82fef76cc2ed0952b6e3034b3b5d87a88f4 Mon Sep 17 00:00:00 2001
From: Philippe Antoine <pantoine@oisf.net>
Date: Tue, 17 Dec 2024 10:30:45 +0100
Subject: [PATCH] doh2: really enforce 65K dns message limit

Ticket: #7464
---
 rules/http2-events.rules |  1 +
 rust/src/http2/http2.rs  | 11 ++++++++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/rules/http2-events.rules b/rules/http2-events.rules
index 413fdd652cad..1cbfa65500e9 100644
--- a/rules/http2-events.rules
+++ b/rules/http2-events.rules
@@ -21,3 +21,4 @@ alert http2 any any -> any any (msg:"SURICATA HTTP2 too many streams"; flow:esta
 alert http2 any any -> any any (msg:"SURICATA HTTP2 authority host mismatch"; flow:established,to_server; app-layer-event:http2.authority_host_mismatch; classtype:protocol-command-decode; sid:2290013; rev:1;)
 alert http2 any any -> any any (msg:"SURICATA HTTP2 user info in uri"; flow:established,to_server; app-layer-event:http2.userinfo_in_uri; classtype:protocol-command-decode; sid:2290014; rev:1;)
 alert http2 any any -> any any (msg:"SURICATA HTTP2 reassembly limit reached"; flow:established; app-layer-event:http2.reassembly_limit_reached; classtype:protocol-command-decode; sid:2290015; rev:1;)
+alert http2 any any -> any any (msg:"SURICATA HTTP2 dns too long"; flow:established; app-layer-event:http2.dns_too_long; classtype:protocol-command-decode; sid:2290016; rev:1;)
diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs
index 8ed0157922ba..de767f4cc123 100644
--- a/rust/src/http2/http2.rs
+++ b/rust/src/http2/http2.rs
@@ -368,9 +368,13 @@ impl HTTP2Transaction {
         if unsafe { ALPROTO_DOH2 } != ALPROTO_UNKNOWN {
             // we store DNS response, and process it when complete
             if let Some(doh) = &mut self.doh {
-                if doh.is_doh_data[dir.index()] && doh.data_buf[dir.index()].len() < 0xFFFF {
-                    // a DNS message is U16_MAX
-                    doh.data_buf[dir.index()].extend_from_slice(decompressed);
+                if doh.is_doh_data[dir.index()] {
+                    if doh.data_buf[dir.index()].len() + decompressed.len() <= 0xFFFF {
+                        // a DNS message is U16_MAX
+                        doh.data_buf[dir.index()].extend_from_slice(decompressed);
+                    } else {
+                        self.set_event(HTTP2Event::DnsTooLong);
+                    }
                 }
             }
         }
@@ -506,6 +510,7 @@ pub enum HTTP2Event {
     AuthorityHostMismatch,
     UserinfoInUri,
     ReassemblyLimitReached,
+    DnsTooLong,
 }
 
 pub struct HTTP2DynTable {