]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Fix malloc corruption from use-after-free in peer_select.cc
authorAmos Jeffries <squid3@treenet.co.nz>
Thu, 3 Apr 2014 10:22:52 +0000 (03:22 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Thu, 3 Apr 2014 10:22:52 +0000 (03:22 -0700)
* Cleanup peer server list of existing in ps_state destructor.

* Abort peer selection if the FwdState CBDATA reference has become
  invalid. ps_state::paths pointer is also invalid.

src/peer_select.cc

index 966a01f23a13713282559ffd08ceeff6113be501..af3c3e78b446c1efe3f8ae5f3e9e625460d194b5 100644 (file)
@@ -90,6 +90,13 @@ CBDATA_CLASS_INIT(ps_state);
 
 ps_state::~ps_state()
 {
+    while (servers) {
+        FwdServer *next = servers->next;
+        cbdataReferenceDone(servers->_peer);
+        memFree(servers, MEM_FWD_SERVER);
+        servers = next;
+    }
+
     if (entry) {
         debugs(44, 3, entry->url());
 
@@ -229,6 +236,12 @@ peerSelectDnsPaths(ps_state *psstate)
 {
     FwdServer *fs = psstate->servers;
 
+    if (!cbdataReferenceValid(psstate->callback_data)) {
+        debugs(44, 3, "Aborting peer selection. Parent Job went away.");
+        delete psstate;
+        return;
+    }
+
     // Bug 3243: CVE 2009-0801
     // Bypass of browser same-origin access control in intercepted communication
     // To resolve this we must use only the original client destination when going DIRECT
@@ -319,6 +332,12 @@ peerSelectDnsResults(const ipcache_addrs *ia, const DnsLookupDetails &details, v
 {
     ps_state *psstate = (ps_state *)data;
 
+    if (!cbdataReferenceValid(psstate->callback_data)) {
+        debugs(44, 3, "Aborting peer selection. Parent Job went away.");
+        delete psstate;
+        return;
+    }
+
     psstate->request->recordLookup(details);
 
     FwdServer *fs = psstate->servers;
@@ -432,6 +451,12 @@ peerCheckNetdbDirect(ps_state * psstate)
 static void
 peerSelectFoo(ps_state * ps)
 {
+    if (!cbdataReferenceValid(ps->callback_data)) {
+        debugs(44, 3, "Aborting peer selection. Parent Job went away.");
+        delete ps;
+        return;
+    }
+
     StoreEntry *entry = ps->entry;
     HttpRequest *request = ps->request;
     debugs(44, 3, "peerSelectFoo: '" << RequestMethodStr(request->method) << " " << request->GetHost() << "'");