From a012aaf9a27aaf416c4a2e1e4e1f5409ca2c760d Mon Sep 17 00:00:00 2001 From: Brian Bockelman Date: Sun, 29 Nov 2015 21:44:40 +0100 Subject: [PATCH] Fail read calls after exception. If a read call was performed after XrdFile threw an exception, it is possible there are no active sources. However, not all paths check for the case of zero sources and may use-after-free the last source. This caused a deadlock at the Tier-0. --- Utilities/XrdAdaptor/src/XrdRequestManager.cc | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/Utilities/XrdAdaptor/src/XrdRequestManager.cc b/Utilities/XrdAdaptor/src/XrdRequestManager.cc index 05c2d3e39bfd4..4a30ef480af66 100644 --- a/Utilities/XrdAdaptor/src/XrdRequestManager.cc +++ b/Utilities/XrdAdaptor/src/XrdRequestManager.cc @@ -392,6 +392,17 @@ std::shared_ptr RequestManager::getActiveFile() { std::lock_guard sentry(m_source_mutex); + if (m_activeSources.empty()) + { + edm::Exception ex(edm::errors::FileReadError); + ex << "XrdAdaptor::RequestManager::getActiveFile(name='" << m_name + << "', flags=0x" << std::hex << m_flags + << ", permissions=0" << std::oct << m_perms << std::dec + << ") => Source used after fatal exception."; + ex.addContext("In XrdAdaptor::RequestManager::handle()"); + addConnections(ex); + throw ex; + } return m_activeSources[0]->getFileHandle(); } @@ -461,6 +472,17 @@ RequestManager::pickSingleSource() m_nextInitialSourceToggle = true; } } + else if (m_activeSources.empty()) + { + edm::Exception ex(edm::errors::FileReadError); + ex << "XrdAdaptor::RequestManager::handle read(name='" << m_name + << "', flags=0x" << std::hex << m_flags + << ", permissions=0" << std::oct << m_perms << std::dec + << ") => Source used after fatal exception."; + ex.addContext("In XrdAdaptor::RequestManager::handle()"); + addConnections(ex); + throw ex; + } else { source = m_activeSources[0]; @@ -569,7 +591,6 @@ XrdAdaptor::RequestManager::handle(std::shared_ptr > io edm::CPUTimer timer; timer.start(); - assert(m_activeSources.size()); if (m_activeSources.size() == 1) { std::shared_ptr c_ptr(new XrdAdaptor::ClientRequest(*this, iolist)); @@ -577,6 +598,18 @@ XrdAdaptor::RequestManager::handle(std::shared_ptr > io m_activeSources[0]->handle(c_ptr); return c_ptr->get_future(); } + // Make sure active + else if (m_activeSources.empty()) + { + edm::Exception ex(edm::errors::FileReadError); + ex << "XrdAdaptor::RequestManager::handle readv(name='" << m_name + << "', flags=0x" << std::hex << m_flags + << ", permissions=0" << std::oct << m_perms << std::dec + << ") => Source used after fatal exception."; + ex.addContext("In XrdAdaptor::RequestManager::handle()"); + addConnections(ex); + throw ex; + } assert(iolist.get()); std::shared_ptr > req1(new std::vector);