This is an automated email from the ASF dual-hosted git repository.

eze pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new dc1a7e3c6f Reject reserved h2 to h3 frame types (#10113)
dc1a7e3c6f is described below

commit dc1a7e3c6f89a3b897054516ec63505fb8c84f9a
Author: Evan Zelkowitz <e...@apache.org>
AuthorDate: Fri Jul 28 14:38:00 2023 -0600

    Reject reserved h2 to h3 frame types (#10113)
---
 proxy/http3/Http3DebugNames.cc                |   6 ++
 proxy/http3/Http3ProtocolEnforcer.cc          |  11 ++-
 proxy/http3/test/test_Http3FrameDispatcher.cc | 130 ++++++++++++++++++++------
 3 files changed, 120 insertions(+), 27 deletions(-)

diff --git a/proxy/http3/Http3DebugNames.cc b/proxy/http3/Http3DebugNames.cc
index 9e3fbf9640..321c33b328 100644
--- a/proxy/http3/Http3DebugNames.cc
+++ b/proxy/http3/Http3DebugNames.cc
@@ -44,6 +44,12 @@ Http3DebugNames::frame_type(Http3FrameType type)
     return "GOAWAY";
   case Http3FrameType::DUPLICATE_PUSH_ID:
     return "DUPLICATE_PUSH_ID";
+  case Http3FrameType::X_RESERVED_1:
+    return "X_RESERVED_1";
+  case Http3FrameType::X_RESERVED_2:
+    return "X_RESERVED_2";
+  case Http3FrameType::X_RESERVED_3:
+    return "X_RESERVED_3";
   case Http3FrameType::UNKNOWN:
   default:
     return "UNKNOWN";
diff --git a/proxy/http3/Http3ProtocolEnforcer.cc 
b/proxy/http3/Http3ProtocolEnforcer.cc
index 9a90cda451..b2b64daad6 100644
--- a/proxy/http3/Http3ProtocolEnforcer.cc
+++ b/proxy/http3/Http3ProtocolEnforcer.cc
@@ -46,11 +46,20 @@ Http3ProtocolEnforcer::handle_frame(std::shared_ptr<const 
Http3Frame> frame, int
     } else if (frame_seq != 0 && f_type == Http3FrameType::SETTINGS) {
       error = 
std::make_unique<Http3ConnectionError>(Http3ErrorCode::H3_FRAME_UNEXPECTED,
                                                      "only one SETTINGS frame 
is allowed per the control stream");
-    } else if (f_type == Http3FrameType::DATA || f_type == 
Http3FrameType::HEADERS) {
+    } else if (f_type == Http3FrameType::DATA || f_type == 
Http3FrameType::HEADERS || f_type == Http3FrameType::X_RESERVED_1 ||
+               f_type == Http3FrameType::X_RESERVED_2 || f_type == 
Http3FrameType::X_RESERVED_3) {
       std::string error_msg = Http3DebugNames::frame_type(f_type);
       error_msg.append(" frame is not allowed on control stream");
       error = 
std::make_unique<Http3ConnectionError>(Http3ErrorCode::H3_FRAME_UNEXPECTED, 
error_msg.c_str());
     }
+  } else {
+    if (f_type == Http3FrameType::X_RESERVED_1 || f_type == 
Http3FrameType::X_RESERVED_2 ||
+        f_type == Http3FrameType::X_RESERVED_3) {
+      std::string error_msg = Http3DebugNames::frame_type(f_type);
+      error_msg.append(" frame is not allowed on any stream");
+      error = 
std::make_unique<Http3ConnectionError>(Http3ErrorCode::H3_FRAME_UNEXPECTED, 
error_msg.c_str());
+    }
   }
+
   return error;
 }
diff --git a/proxy/http3/test/test_Http3FrameDispatcher.cc 
b/proxy/http3/test/test_Http3FrameDispatcher.cc
index 8ba980e202..0987e4e8dd 100644
--- a/proxy/http3/test/test_Http3FrameDispatcher.cc
+++ b/proxy/http3/test/test_Http3FrameDispatcher.cc
@@ -29,32 +29,37 @@
 
 TEST_CASE("Http3FrameHandler dispatch", "[http3]")
 {
-  uint8_t input[] = {// 1st frame (HEADERS)
-                     0x01, 0x04, 0x11, 0x22, 0x33, 0x44,
-                     // 2nd frame (DATA)
-                     0x00, 0x04, 0xaa, 0xbb, 0xcc, 0xdd,
-                     // 3rd frame (incomplete)
-                     0xff};
-
-  Http3FrameDispatcher http3FrameDispatcher;
-  Http3MockFrameHandler handler;
-  http3FrameDispatcher.add_handler(&handler);
-
-  MIOBuffer *buf         = new_MIOBuffer(BUFFER_SIZE_INDEX_512);
-  IOBufferReader *reader = buf->alloc_reader();
-  uint64_t nread         = 0;
-  Http3ErrorUPtr error   = Http3ErrorUPtr(new Http3NoError());
-
-  buf->write(input, sizeof(input));
-
-  // Initial state
-  CHECK(handler.total_frame_received == 0);
-  CHECK(nread == 0);
-
-  error = http3FrameDispatcher.on_read_ready(0, Http3StreamType::UNKNOWN, 
*reader, nread);
-  CHECK(error->app_error_code == Http3ErrorCode::H3_NO_ERROR);
-  CHECK(handler.total_frame_received == 1);
-  CHECK(nread == 12);
+  SECTION("Test good case")
+  {
+    uint8_t input[] = {// 1st frame (HEADERS)
+                       0x01, 0x04, 0x11, 0x22, 0x33, 0x44,
+                       // 2nd frame (DATA)
+                       0x00, 0x04, 0xaa, 0xbb, 0xcc, 0xdd,
+                       // 3rd frame (incomplete)
+                       0xff};
+
+    Http3FrameDispatcher http3FrameDispatcher;
+    Http3MockFrameHandler handler;
+    Http3ProtocolEnforcer enforcer;
+    http3FrameDispatcher.add_handler(&handler);
+    http3FrameDispatcher.add_handler(&enforcer);
+
+    MIOBuffer *buf         = new_MIOBuffer(BUFFER_SIZE_INDEX_512);
+    IOBufferReader *reader = buf->alloc_reader();
+    uint64_t nread         = 0;
+    Http3ErrorUPtr error   = Http3ErrorUPtr(new Http3NoError());
+
+    buf->write(input, sizeof(input));
+
+    // Initial state
+    CHECK(handler.total_frame_received == 0);
+    CHECK(nread == 0);
+
+    error = http3FrameDispatcher.on_read_ready(0, Http3StreamType::UNKNOWN, 
*reader, nread);
+    CHECK(error->app_error_code == Http3ErrorCode::H3_NO_ERROR);
+    CHECK(handler.total_frame_received == 1);
+    CHECK(nread == 12);
+  }
 }
 
 TEST_CASE("control stream tests", "[http3]")
@@ -219,6 +224,44 @@ TEST_CASE("control stream tests", "[http3]")
     CHECK(handler.total_frame_received == 1);
     CHECK(nread == sizeof(input));
   }
+
+  SECTION("RESERVED frame is not allowed on control stream")
+  {
+    uint8_t input[] = {0x04,       // Type
+                       0x08,       // Length
+                       0x06,       // Identifier
+                       0x44, 0x00, // Value
+                       0x09,       // Identifier
+                       0x0f,       // Value
+                       0x4a, 0x0a, // Identifier
+                       0x00,       // Value
+                       0x06,       // Type
+                       0x04,       // Length
+                       0x11, 0x22, 0x33, 0x44};
+
+    Http3FrameDispatcher http3FrameDispatcher;
+    Http3ProtocolEnforcer enforcer;
+    Http3MockFrameHandler handler;
+
+    http3FrameDispatcher.add_handler(&enforcer);
+    http3FrameDispatcher.add_handler(&handler);
+
+    MIOBuffer *buf         = new_MIOBuffer(BUFFER_SIZE_INDEX_512);
+    IOBufferReader *reader = buf->alloc_reader();
+    uint64_t nread         = 0;
+    Http3ErrorUPtr error   = Http3ErrorUPtr(new Http3NoError());
+
+    buf->write(input, sizeof(input));
+
+    // Initial state
+    CHECK(handler.total_frame_received == 0);
+    CHECK(nread == 0);
+
+    error = http3FrameDispatcher.on_read_ready(0, Http3StreamType::CONTROL, 
*reader, nread);
+    CHECK(error->app_error_code == Http3ErrorCode::H3_FRAME_UNEXPECTED);
+    CHECK(handler.total_frame_received == 1);
+    CHECK(nread == sizeof(input));
+  }
 }
 
 TEST_CASE("ignore unknown frames", "[http3]")
@@ -244,3 +287,38 @@ TEST_CASE("ignore unknown frames", "[http3]")
     CHECK(nread == 0);
   }
 }
+
+TEST_CASE("Reserved frame type not allowed", "[http3]")
+{
+  SECTION("Reject reserved frame type in non control stream")
+  {
+    uint8_t input[] = {// 1st frame (HEADERS)
+                       0x01, 0x04, 0x11, 0x22, 0x33, 0x44,
+                       // 2nd frame (DATA)
+                       0x06, 0x04, 0xaa, 0xbb, 0xcc, 0xdd,
+                       // 3rd frame (incomplete)
+                       0xff};
+
+    Http3FrameDispatcher http3FrameDispatcher;
+    Http3MockFrameHandler handler;
+    Http3ProtocolEnforcer enforcer;
+    http3FrameDispatcher.add_handler(&handler);
+    http3FrameDispatcher.add_handler(&enforcer);
+
+    MIOBuffer *buf         = new_MIOBuffer(BUFFER_SIZE_INDEX_512);
+    IOBufferReader *reader = buf->alloc_reader();
+    uint64_t nread         = 0;
+    Http3ErrorUPtr error   = Http3ErrorUPtr(new Http3NoError());
+
+    buf->write(input, sizeof(input));
+
+    // Initial state
+    CHECK(handler.total_frame_received == 0);
+    CHECK(nread == 0);
+
+    error = http3FrameDispatcher.on_read_ready(0, Http3StreamType::UNKNOWN, 
*reader, nread);
+    CHECK(error->app_error_code == Http3ErrorCode::H3_FRAME_UNEXPECTED);
+    CHECK(handler.total_frame_received == 0);
+    CHECK(nread == 12);
+  }
+}

Reply via email to