]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Fix SIGSEGV in ESIContext response handling
authorAmos Jeffries <squid3@treenet.co.nz>
Wed, 4 May 2016 03:31:48 +0000 (15:31 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Wed, 4 May 2016 03:31:48 +0000 (15:31 +1200)
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.

src/esi/Assign.cc
src/esi/Context.h
src/esi/Esi.cc

index d0cc6f91ec6562e04daed7c2bc6189df3a77c95a..47c12a6144b1d7b74d39b8d30754d8e5e4a248a4 100644 (file)
@@ -18,6 +18,7 @@
 #include "esi/Assign.h"
 #include "esi/Context.h"
 #include "esi/Sequence.h"
+#include "HttpReply.h"
 
 ESIAssign::~ESIAssign()
 {
index 27df1ba62c69ec3431e89af1fd0cad5f3308b941..ee2f6f15acff5e812f52b8b30db3a9afddcaf6ec 100644 (file)
@@ -13,6 +13,7 @@
 #include "err_type.h"
 #include "esi/Element.h"
 #include "esi/Parser.h"
+#include "http/forward.h"
 #include "http/StatusCode.h"
 
 class ESIVarState;
@@ -92,7 +93,7 @@ public:
     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 */
+    HttpReplyPointer 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
index 801cb045d61ae8d179a35432cfdc1b1648671a49..4a960198f5609b1b62c4263a279ac79a74487a08 100644 (file)
@@ -605,18 +605,18 @@ ESIContext::send ()
     flags.clientwantsdata = 0;
     debugs(86, 5, "ESIContext::send: this=" << this << " Client no longer wants data ");
     /* Deal with re-entrancy */
-    HttpReply *temprep = rep;
+    HttpReplyPointer temprep = rep;
     rep = NULL; /* freed downstream */
 
     if (temprep && varState)
-        varState->buildVary (temprep);
+        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)
@@ -1385,7 +1385,7 @@ ESIContext::freeResources ()
 {
     debugs(86, 5, HERE << "Freeing for this=" << this);
 
-    HTTPMSGUNLOCK(rep);
+    rep = nullptr; // refcounted
 
     finishChildren ();