Hi,
I have backported r791454 to 2.2.3 in Debian 4.0 and have received a
report [1] about segfaults with mod_deflate and mod_php (5.2.0). As
far as I understand it, the reason is that mod_php uses ap_rwrite
which creates transient buckets. When the connection is closed by the
client, these buckets sometimes stay in the bucket brigade when
ap_pass_brigade returns an error for the compressed data of an
earlier bucket. If deflate_out_filter gets called again with the same
brigade, the memory of the transient buckets is no longer valid,
causing a segfault.
This patch seems to fix the issue:
--- apache2-2.2.3~/modules/filters/mod_deflate.c
+++ apache2-2.2.3/modules/filters/mod_deflate.c
@@ -512,6 +512,7 @@
APR_BRIGADE_INSERT_TAIL(ctx->bb, bkt);
rv = ap_pass_brigade(f->next, ctx->bb);
if (rv != APR_SUCCESS) {
+ apr_brigade_cleanup(bb);
return rv;
}
continue;
@@ -543,6 +544,7 @@
/* Send what we have right now to the next filter. */
rv = ap_pass_brigade(f->next, ctx->bb);
if (rv != APR_SUCCESS) {
+ apr_brigade_cleanup(bb);
return rv;
}
}
I could not reproduce the segfault with Debian 5.0, containing Apache
2.2.9 and php 5.2.8. The same for Debian unstable with 2.2.12 and php
5.2.10. Therefore, I also tried to take the whole mod_deflate.c from
2.2.9 into 2.2.3, but it did not fix the segfaults [2].
Is there some change from 2.2.3 to 2.2.9 (which cannot be in
mod_deflate.c) that fixes the issue? Or is it just coincidence that
2.2.9 and 2.2.12 do not segfault and should the above patch be
included in the next 2.2.x?
Cheers,
Stefan
[1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=537665
[2] to reproduce, use this script
<?php
for ($i = 0; $i < 100000; $i++ ) {
echo "blah\n";
echo $i;
}
echo "blubb\n";
and request it with
curl -is -H 'Accept-Encoding: gzip' http://localhost/x.php |head -10
With 2.2.3, I get a segfault for about 30% of the requests.