trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sor...@apache.org
Subject [trafficserver] branch 6.2.x updated: TS-5019: Add total header length checks in HPACK
Date Wed, 02 Nov 2016 12:52:43 GMT
This is an automated email from the ASF dual-hosted git repository.

sorber pushed a commit to branch 6.2.x
in repository https://git-dual.apache.org/repos/asf/trafficserver.git

The following commit(s) were added to refs/heads/6.2.x by this push:
       new  ec65b34   TS-5019: Add total header length checks in HPACK
ec65b34 is described below

commit ec65b347b7ee68f88bac172dddf09a0ee96c1e10
Author: Masaori Koshiba <masaori@apache.org>
AuthorDate: Fri Oct 28 08:18:58 2016 +0900

    TS-5019: Add total header length checks in HPACK
    
    (cherry picked from commit a5c11a863d961099af500649c4669fb711d48991)
    
    Conflicts:
    	proxy/http2/Http2Stream.h
    	proxy/http2/test_HPACK.cc
---
 proxy/http2/HPACK.cc                | 16 +++++++++++++++-
 proxy/http2/HPACK.h                 |  6 ++++--
 proxy/http2/HTTP2.cc                |  5 ++++-
 proxy/http2/Http2ConnectionState.cc |  4 ++++
 proxy/http2/Http2Stream.cc          |  7 +++++++
 proxy/http2/Http2Stream.h           |  8 ++++----
 proxy/http2/RegressionHPACK.cc      |  3 ++-
 7 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/proxy/http2/HPACK.cc b/proxy/http2/HPACK.cc
index a31e0db..188cb88 100644
--- a/proxy/http2/HPACK.cc
+++ b/proxy/http2/HPACK.cc
@@ -834,7 +834,8 @@ update_dynamic_table_size(const uint8_t *buf_start, const uint8_t *buf_end,
Hpac
 }
 
 int64_t
-hpack_decode_header_block(HpackIndexingTable &indexing_table, HTTPHdr *hdr, const uint8_t
*in_buf, const size_t in_buf_len)
+hpack_decode_header_block(HpackIndexingTable &indexing_table, HTTPHdr *hdr, const uint8_t
*in_buf, const size_t in_buf_len,
+                          uint32_t max_header_size)
 {
   const uint8_t *cursor           = in_buf;
   const uint8_t *const in_buf_end = in_buf + in_buf_len;
@@ -842,6 +843,7 @@ hpack_decode_header_block(HpackIndexingTable &indexing_table, HTTPHdr
*hdr, cons
   HTTPHdrImpl *hh                 = hdr->m_http;
   bool header_field_started       = false;
   bool has_http2_violation        = false;
+  uint32_t total_header_size      = 0;
 
   while (cursor < in_buf_end) {
     int64_t read_bytes = 0;
@@ -885,6 +887,18 @@ hpack_decode_header_block(HpackIndexingTable &indexing_table, HTTPHdr
*hdr, cons
       cursor += read_bytes;
       continue;
     }
+
+    int name_len  = 0;
+    int value_len = 0;
+
+    field->name_get(&name_len);
+    field->value_get(&value_len);
+    total_header_size += name_len + value_len;
+
+    if (total_header_size > max_header_size) {
+      return HPACK_ERROR_SIZE_EXCEEDED_ERROR;
+    }
+
     // Store to HdrHeap
     mime_hdr_field_attach(hh->m_fields_impl, field, 1, NULL);
   }
diff --git a/proxy/http2/HPACK.h b/proxy/http2/HPACK.h
index cf57f7d..e0c60f9 100644
--- a/proxy/http2/HPACK.h
+++ b/proxy/http2/HPACK.h
@@ -30,7 +30,8 @@
 #include "HTTP.h"
 
 // It means that any header field can be compressed/decompressed by ATS
-const static int HPACK_ERROR_COMPRESSION_ERROR = -1;
+const static int HPACK_ERROR_COMPRESSION_ERROR   = -1;
+const static int HPACK_ERROR_SIZE_EXCEEDED_ERROR = -2;
 
 enum HpackFieldType {
   HPACK_FIELD_INDEX,              // [RFC 7541] 6.1. Indexed Header Field Representation
@@ -170,7 +171,8 @@ int64_t update_dynamic_table_size(const uint8_t *buf_start, const uint8_t
*buf_e
 
 // High level interfaces
 typedef HpackIndexingTable HpackHandle;
-int64_t hpack_decode_header_block(HpackHandle &handle, HTTPHdr *hdr, const uint8_t *in_buf,
const size_t in_buf_len);
+int64_t hpack_decode_header_block(HpackHandle &handle, HTTPHdr *hdr, const uint8_t *in_buf,
const size_t in_buf_len,
+                                  uint32_t max_header_size);
 int64_t hpack_encode_header_block(HpackHandle &handle, uint8_t *out_buf, const size_t
out_buf_len, HTTPHdr *hdr);
 
 #endif /* __HPACK_H__ */
diff --git a/proxy/http2/HTTP2.cc b/proxy/http2/HTTP2.cc
index 00a09b0..fc884af 100644
--- a/proxy/http2/HTTP2.cc
+++ b/proxy/http2/HTTP2.cc
@@ -572,12 +572,15 @@ http2_decode_header_blocks(HTTPHdr *hdr, const uint8_t *buf_start, const
uint32_
   const char *value;
   int len;
   bool is_trailing_header = trailing_header;
-  int64_t result          = hpack_decode_header_block(handle, hdr, buf_start, buf_len);
+  int64_t result          = hpack_decode_header_block(handle, hdr, buf_start, buf_len, Http2::max_request_header_size);
 
   if (result < 0) {
     if (result == HPACK_ERROR_COMPRESSION_ERROR) {
       return HTTP2_ERROR_COMPRESSION_ERROR;
+    } else if (result == HPACK_ERROR_SIZE_EXCEEDED_ERROR) {
+      return HTTP2_ERROR_ENHANCE_YOUR_CALM;
     }
+
     return HTTP2_ERROR_PROTOCOL_ERROR;
   }
   if (len_read) {
diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc
index be863e1..ab3a4ed 100644
--- a/proxy/http2/Http2ConnectionState.cc
+++ b/proxy/http2/Http2ConnectionState.cc
@@ -299,6 +299,8 @@ rcv_headers_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
     if (result != HTTP2_ERROR_NO_ERROR) {
       if (result == HTTP2_ERROR_COMPRESSION_ERROR) {
         return Http2Error(HTTP2_ERROR_CLASS_CONNECTION, HTTP2_ERROR_COMPRESSION_ERROR);
+      } else if (result == HTTP2_ERROR_ENHANCE_YOUR_CALM) {
+        return Http2Error(HTTP2_ERROR_CLASS_CONNECTION, HTTP2_ERROR_ENHANCE_YOUR_CALM);
       } else {
         return Http2Error(HTTP2_ERROR_CLASS_STREAM, HTTP2_ERROR_PROTOCOL_ERROR);
       }
@@ -730,6 +732,8 @@ rcv_continuation_frame(Http2ConnectionState &cstate, const Http2Frame
&frame)
     if (result != HTTP2_ERROR_NO_ERROR) {
       if (result == HTTP2_ERROR_COMPRESSION_ERROR) {
         return Http2Error(HTTP2_ERROR_CLASS_CONNECTION, HTTP2_ERROR_COMPRESSION_ERROR);
+      } else if (result == HTTP2_ERROR_ENHANCE_YOUR_CALM) {
+        return Http2Error(HTTP2_ERROR_CLASS_CONNECTION, HTTP2_ERROR_ENHANCE_YOUR_CALM);
       } else {
         return Http2Error(HTTP2_ERROR_CLASS_STREAM, HTTP2_ERROR_PROTOCOL_ERROR);
       }
diff --git a/proxy/http2/Http2Stream.cc b/proxy/http2/Http2Stream.cc
index 281a037..6e9079f 100644
--- a/proxy/http2/Http2Stream.cc
+++ b/proxy/http2/Http2Stream.cc
@@ -122,6 +122,13 @@ Http2Stream::main_event_handler(int event, void *edata)
   return 0;
 }
 
+Http2ErrorCode
+Http2Stream::decode_header_blocks(HpackHandle &hpack_handle)
+{
+  return http2_decode_header_blocks(&_req_header, (const uint8_t *)header_blocks, header_blocks_length,
NULL, hpack_handle,
+                                    trailing_header);
+}
+
 void
 Http2Stream::send_request(Http2ConnectionState &cstate)
 {
diff --git a/proxy/http2/Http2Stream.h b/proxy/http2/Http2Stream.h
index 5966522..0f19564 100644
--- a/proxy/http2/Http2Stream.h
+++ b/proxy/http2/Http2Stream.h
@@ -135,11 +135,10 @@ public:
     return trailing_header;
   }
 
-  Http2ErrorCode
-  decode_header_blocks(HpackHandle &hpack_handle)
+  void
+  set_request_headers(HTTPHdr &h2_headers)
   {
-    return http2_decode_header_blocks(&_req_header, (const uint8_t *)header_blocks, header_blocks_length,
NULL, hpack_handle,
-                                      trailing_header);
+    _req_header.copy(&h2_headers);
   }
 
   // Check entire DATA payload length if content-length: header is exist
@@ -155,6 +154,7 @@ public:
     return content_length == 0 || content_length == data_length;
   }
 
+  Http2ErrorCode decode_header_blocks(HpackHandle &hpack_handle);
   void send_request(Http2ConnectionState &cstate);
   VIO *do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf);
   VIO *do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *abuffer, bool owner =
false);
diff --git a/proxy/http2/RegressionHPACK.cc b/proxy/http2/RegressionHPACK.cc
index 4e506b3..9904981 100644
--- a/proxy/http2/RegressionHPACK.cc
+++ b/proxy/http2/RegressionHPACK.cc
@@ -29,6 +29,7 @@
 const static int DYNAMIC_TABLE_SIZE_FOR_REGRESSION_TEST = 256;
 const static int BUFSIZE_FOR_REGRESSION_TEST            = 128;
 const static int MAX_TEST_FIELD_NUM                     = 8;
+const static int MAX_REQUEST_HEADER_SIZE                = 131072;
 
 /***********************************************************************************
  *                                                                                 *
@@ -562,7 +563,7 @@ REGRESSION_TEST(HPACK_Decode)(RegressionTest *t, int, int *pstatus)
     headers->create(HTTP_TYPE_REQUEST);
 
     hpack_decode_header_block(indexing_table, headers, encoded_field_request_test_case[i].encoded_field,
-                              encoded_field_request_test_case[i].encoded_field_len);
+                              encoded_field_request_test_case[i].encoded_field_len, MAX_REQUEST_HEADER_SIZE);
 
     for (unsigned int j = 0; j < sizeof(raw_field_request_test_case[i]) / sizeof(raw_field_request_test_case[i][0]);
j++) {
       const char *expected_name  = raw_field_request_test_case[i][j].raw_name;

-- 
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <commits@trafficserver.apache.org>'].

Mime
View raw message