From: Amos Jeffries Date: Thu, 3 Apr 2014 10:22:52 +0000 (-0700) Subject: Fix malloc corruption from use-after-free in peer_select.cc X-Git-Tag: SQUID_3_5_0_1~305 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3633974207ffbd8edd214c08dea9be0966334068;p=thirdparty%2Fsquid.git Fix malloc corruption from use-after-free in peer_select.cc * 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. --- diff --git a/src/peer_select.cc b/src/peer_select.cc index 966a01f23a..af3c3e78b4 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -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() << "'");