Author: rhuijben
Date: Sat Oct 31 21:32:24 2015
New Revision: 1711688

URL: http://svn.apache.org/viewvc?rev=1711688&view=rev
Log:
Add a sane maximum per header line maximum in the hpack buckets
as a simple fix for a buffer overflow triggered by passing
APR_UINT32_MAX as maximum size. Add config support and use this
for a bit of logging.

* buckets/hpack_buckets.c
  (serf_hpack_decode_ctx_t): Add config member.
  (serf__bucket_hpack_decode_create): Apply maximum.
  (handle_read_entry_and_clear): Log entries.
  (serf_hpack_decode_set_config): New function.
  (serf_bucket_type__hpack_decode): Declare as v2 bucket and
    add config handler.

Modified:
    serf/trunk/buckets/hpack_buckets.c

Modified: serf/trunk/buckets/hpack_buckets.c
URL: 
http://svn.apache.org/viewvc/serf/trunk/buckets/hpack_buckets.c?rev=1711688&r1=1711687&r2=1711688&view=diff
==============================================================================
--- serf/trunk/buckets/hpack_buckets.c (original)
+++ serf/trunk/buckets/hpack_buckets.c Sat Oct 31 21:32:24 2015
@@ -884,6 +884,7 @@ typedef struct serf_hpack_decode_ctx_t
   /* When producing HTTP/1.1 style output */
   serf_bucket_t *agg;
   serf_databuf_t databuf;
+  serf_config_t *config;
 
   char wrote_header;
   char hit_eof;
@@ -916,6 +917,9 @@ serf__bucket_hpack_decode_create(serf_bu
   ctx->stream = stream;
   ctx->max_entry_size = max_entry_size;
 
+  if (max_entry_size > 0x0100000)
+    max_entry_size = 0x0100000; /* 1 MB */
+
   ctx->buffer_size = max_entry_size + 16;
   ctx->buffer_used = 0;
   ctx->buffer = serf_bucket_mem_alloc(alloc, ctx->buffer_size);
@@ -1026,6 +1030,10 @@ handle_read_entry_and_clear(serf_hpack_d
   char own_key;
   char own_val;
 
+  serf__log(LOGLVL_INFO, SERF_LOGCOMP_PROTOCOL, __FILE__, ctx->config,
+            "Parsed from HPACK: %.*s: %.*s\n",
+            ctx->key_size, ctx->key, ctx->val_size, ctx->val);
+
   if (ctx->item_callback)
     {
       status = ctx->item_callback(ctx->item_baton,
@@ -1550,6 +1558,28 @@ serf_hpack_decode_peek(serf_bucket_t *bu
   return status;
 }
 
+static apr_status_t
+serf_hpack_decode_set_config(serf_bucket_t *bucket,
+                             serf_config_t *config)
+{
+  serf_hpack_decode_ctx_t *ctx = bucket->data;
+  apr_status_t status;
+
+  ctx->config = config;
+
+  status = serf_bucket_set_config(ctx->stream, config);
+  if (status)
+    return status;
+
+  if (ctx->agg)
+    {
+      status = serf_bucket_set_config(ctx->agg, config);
+      if (status)
+        return status;
+    }
+  return APR_SUCCESS;
+}
+
 static void
 serf_hpack_decode_destroy(serf_bucket_t *bucket)
 {
@@ -1572,7 +1602,10 @@ const serf_bucket_type_t serf_bucket_typ
   serf_hpack_decode_readline,
   serf_default_read_iovec,
   serf_default_read_for_sendfile,
-  serf_default_read_bucket,
+  serf_buckets_are_v2,
   serf_hpack_decode_peek,
-  serf_hpack_decode_destroy
+  serf_hpack_decode_destroy,
+  serf_default_read_bucket,
+  serf_default_get_remaining,
+  serf_hpack_decode_set_config
 };


Reply via email to