From 3633974207ffbd8edd214c08dea9be0966334068 Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Thu, 3 Apr 2014 03:22:52 -0700 Subject: [PATCH] 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. --- src/peer_select.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) 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() << "'"); -- 2.47.2