ASF Bugzilla – Attachment 30285 Details for
Bug 46146
deflate_in_filter fails to inflate if CRC/length bytes are not in available stream
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for bug 46146 where mod_deflate does not wait for all the validation data before trying to validate the input Patch is for 2.2.24
bug_46146-2.2.24.patch (text/plain), 8.38 KB, created by
Kevin Sacry
on 2013-05-15 15:26:41 UTC
(
hide
)
Description:
Patch for bug 46146 where mod_deflate does not wait for all the validation data before trying to validate the input Patch is for 2.2.24
Filename:
MIME Type:
Creator:
Kevin Sacry
Created:
2013-05-15 15:26:41 UTC
Size:
8.38 KB
patch
obsolete
>--- modules/filters/mod_deflate.orig 2013-04-09 12:36:02.230193812 -0600 >+++ modules/filters/mod_deflate.c 2013-05-15 09:22:02.561229976 -0600 >@@ -784,12 +784,22 @@ > ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc); > ctx->proc_bb = apr_brigade_create(r->pool, f->c->bucket_alloc); > ctx->buffer = apr_palloc(r->pool, c->bufferSize); >+ ctx->libz_end_func = inflateEnd; >+ ctx->validation_buffer = NULL; >+ ctx->validation_buffer_length = 0; > > rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES, block, 10); > if (rv != APR_SUCCESS) { > return rv; > } > >+ /* >+ * Register a cleanup function to ensure that we cleanup the internal >+ * libz resources. >+ */ >+ apr_pool_cleanup_register(r->pool, ctx, deflate_ctx_cleanup, >+ apr_pool_cleanup_null); >+ > apr_table_unset(r->headers_in, "Content-Length"); > apr_table_unset(r->headers_in, "Content-MD5"); > >@@ -803,6 +813,8 @@ > if (len != 10 || > deflate_hdr[0] != deflate_magic[0] || > deflate_hdr[1] != deflate_magic[1]) { >+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, >+ "Zlib: didn't recieve valid gzip magic bytes"); > return APR_EGENERAL; > } > >@@ -829,6 +841,7 @@ > ctx->stream.avail_out = c->bufferSize; > > apr_brigade_cleanup(ctx->bb); >+ ctx->inflate_init = 1; > } > > if (APR_BRIGADE_EMPTY(ctx->proc_bb)) { >@@ -847,10 +860,50 @@ > const char *data; > apr_size_t len; > >- /* If we actually see the EOS, that means we screwed up! */ > if (APR_BUCKET_IS_EOS(bkt)) { >+ apr_bucket *eos; >+ ap_remove_output_filter(f); >+ ctx->stream.avail_in = 0; >+ if (ctx->validation_buffer_length == VALIDATION_SIZE) { >+ unsigned long compCRC, compLen; >+ compCRC = getLong(ctx->validation_buffer); >+ if (ctx->crc != compCRC) { >+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, >+ "Zlib: Checksum of inflated stream invalid: " >+ "%ld != %ld", >+ ctx->crc, compCRC); >+ return APR_EGENERAL; >+ } >+ ctx->validation_buffer += VALIDATION_SIZE / 2; >+ compLen = getLong(ctx->validation_buffer); >+ if (ctx->stream.total_out != compLen) { >+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, >+ "Zlib: Length of inflated stream invalid: " >+ "%ld != %ld", ctx->stream.total_out, >+ compLen); >+ return APR_EGENERAL; >+ } >+ } else if (ctx->inflate_init != -1){ >+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, >+ "Zlib: Validation bytes not present"); >+ return APR_EGENERAL; >+ } > inflateEnd(&ctx->stream); >- return APR_EGENERAL; >+ ctx->validation_buffer = NULL; >+ ctx->validation_buffer_length = 0; >+ /* No need for cleanup any longer */ >+ apr_pool_cleanup_kill(r->pool, ctx, deflate_ctx_cleanup); >+ >+ eos = apr_bucket_eos_create(f->c->bucket_alloc); >+ APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, eos); >+ >+ /* >+ * Okay, we've seen the EOS. >+ * Time to pass it along down the chain. >+ */ >+ >+ ctx->inflate_init = -1; >+ return ap_pass_brigade(f->next, ctx->bb); > } > > if (APR_BUCKET_IS_FLUSH(bkt)) { >@@ -885,6 +938,35 @@ > > zRC = Z_OK; > >+ if (ctx->validation_buffer) { >+ if (ctx->validation_buffer_length < VALIDATION_SIZE) { >+ apr_size_t copy_size; >+ >+ copy_size = VALIDATION_SIZE - ctx->validation_buffer_length; >+ if (copy_size > ctx->stream.avail_in) >+ copy_size = ctx->stream.avail_in; >+ memcpy(ctx->validation_buffer + ctx->validation_buffer_length, >+ ctx->stream.next_in, copy_size); >+ /* Saved copy_size bytes */ >+ ctx->stream.avail_in -= copy_size; >+ ctx->validation_buffer_length += copy_size; >+ } >+ >+ if (ctx->stream.avail_in) { >+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, >+ "Zlib: %d bytes of garbage at the end of " >+ "compressed stream.", ctx->stream.avail_in); >+ /* >+ * There is nothing worth consuming for zlib left, because it is >+ * either garbage data or the data has been copied to the >+ * validation buffer (processing validation data is no business >+ * for zlib). So set ctx->stream.avail_in to zero to indicate >+ * this to the following while loop. >+ */ >+ ctx->stream.avail_in = 0; >+ } >+ } >+ > while (ctx->stream.avail_in != 0) { > if (ctx->stream.avail_out == 0) { > apr_bucket *tmp_heap; >@@ -910,7 +992,7 @@ > } > } > if (zRC == Z_STREAM_END) { >- apr_bucket *tmp_heap, *eos; >+ apr_bucket *tmp_heap; > > ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, > "Zlib: Inflated %ld to %ld : URL %s", >@@ -925,36 +1007,25 @@ > APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap); > ctx->stream.avail_out = c->bufferSize; > >- /* Is the remaining 8 bytes already in the avail stream? */ >- if (ctx->stream.avail_in >= 8) { >- unsigned long compCRC, compLen; >- compCRC = getLong(ctx->stream.next_in); >- if (ctx->crc != compCRC) { >- inflateEnd(&ctx->stream); >- return APR_EGENERAL; >- } >- ctx->stream.next_in += 4; >- compLen = getLong(ctx->stream.next_in); >- if (ctx->stream.total_out != compLen) { >- inflateEnd(&ctx->stream); >- return APR_EGENERAL; >- } >- } >- else { >+ /* >+ * We have inflated all data. Now try to capture the >+ * validation bytes. We may not have them all available >+ * right now, but capture what is there. >+ */ >+ ctx->validation_buffer = apr_pcalloc(f->r->pool, >+ VALIDATION_SIZE); >+ if (ctx->stream.avail_in > VALIDATION_SIZE) { >+ ctx->validation_buffer_length = VALIDATION_SIZE; > ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, >- "bytes left after Z_STREAM_END bucket:%ld", >- ctx->stream.avail_in); >- /* FIXME: We need to grab the 8 verification bytes >- * from the wire! */ >- inflateEnd(&ctx->stream); >- return APR_EGENERAL; >- } >- >- inflateEnd(&ctx->stream); >- >- eos = apr_bucket_eos_create(f->c->bucket_alloc); >- APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, eos); >- break; >+ "Zlib: %d bytes of garbage at the end of " >+ "compressed stream.", >+ ctx->stream.avail_in - VALIDATION_SIZE); >+ } else if (ctx->stream.avail_in > 0) { >+ ctx->validation_buffer_length = ctx->stream.avail_in; >+ } >+ if (ctx->validation_buffer_length) >+ memcpy(ctx->validation_buffer, ctx->stream.next_in, >+ ctx->validation_buffer_length); > } > > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 46146
:
30285
|
30314
|
31259
|
31526
|
31527
|
31528