------------------------------------------------------------
revno: 14046
revision-id: squid3@treenet.co.nz-20160506093948-dwt2273wxap81k4i
parent: squid3@treenet.co.nz-20160506082429-dncrbuwz2063r0mm
committer: Amos Jeffries <squid3@treenet.co.nz>
branch nick: 3.5
timestamp: Fri 2016-05-06 21:39:48 +1200
message:
Fix SIGSEGV in ESIContext response handling
HttpReply pointer was being unlocked without heving been locked.
Resulting in a double-free. Make it use RefCount instead of
manual locking to ensure locked/unlock is always symmetrical.
------------------------------------------------------------
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: squid3@treenet.co.nz-20160506093948-dwt2273wxap81k4i
# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5
# testament_sha1: ee8e28be0afa80d08b7d7513aa3eb351f803608f
# timestamp: 2016-05-06 09:50:46 +0000
# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5
# base_revision_id: squid3@treenet.co.nz-20160506082429-\
# dncrbuwz2063r0mm
#
# Begin patch
=== modified file 'src/esi/Context.h'
--- src/esi/Context.h 2016-01-01 00:14:27 +0000
+++ src/esi/Context.h 2016-05-06 09:39:48 +0000
@@ -13,6 +13,7 @@
#include "err_type.h"
#include "esi/Element.h"
#include "esi/Parser.h"
+#include "HttpReply.h"
#include "http/StatusCode.h"
class ESIVarState;
@@ -91,7 +92,7 @@
err_type errorpage; /* if we error what page to use */
Http::StatusCode errorstatus; /* if we error, what code to return */
char *errormessage; /* error to pass to error page */
- HttpReply *rep; /* buffered until we pass data downstream */
+ HttpReply::Pointer rep; /* buffered until we pass data downstream */
ESISegment::Pointer buffered; /* unprocessed data - for whatever reason */
ESISegment::Pointer incoming;
/* processed data we are waiting to send, or for
=== modified file 'src/esi/Esi.cc'
--- src/esi/Esi.cc 2016-04-20 06:36:04 +0000
+++ src/esi/Esi.cc 2016-05-06 09:39:48 +0000
@@ -573,7 +573,7 @@
#endif
- if (!(rep || (outbound.getRaw() &&
+ if (!(rep != NULL || (outbound.getRaw() &&
outbound->len && (outbound_offset <= outbound->len)))) {
debugs(86, 5, "ESIContext::send: Nothing to send.");
return 0;
@@ -618,18 +618,18 @@
flags.clientwantsdata = 0;
debugs(86, 5, "ESIContext::send: this=" << this << " Client no longer wants data ");
/* Deal with re-entrancy */
- HttpReply *temprep = rep;
+ HttpReply::Pointer temprep = rep;
rep = NULL; /* freed downstream */
- if (temprep && varState)
- varState->buildVary (temprep);
+ if (temprep != NULL && varState)
+ varState->buildVary(temprep.getRaw());
{
StoreIOBuffer tempBuffer;
tempBuffer.length = len;
tempBuffer.offset = pos - len;
tempBuffer.data = next->readBuffer.data;
- clientStreamCallback (thisNode, http, temprep, tempBuffer);
+ clientStreamCallback (thisNode, http, temprep.getRaw(), tempBuffer);
}
if (len == 0)
@@ -1259,7 +1259,7 @@
++parserState.stackdepth;
}
- if (rep && !parserState.inited())
+ if (rep != NULL && !parserState.inited())
parserState.init(this);
/* we have data */
@@ -1398,7 +1398,7 @@
{
debugs(86, 5, HERE << "Freeing for this=" << this);
- HTTPMSGUNLOCK(rep);
+ rep = NULL; // refcounted
finishChildren ();