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 };