Skip to content

Commit

Permalink
Prevent data corruption in dvbchannel.cpp causing hang
Browse files Browse the repository at this point in the history
m_is_open was being corrupted by multiple simultaneous modifications,
leading to it managing to create infinite loops within its underlying
data structure. This patch extends the locking of m_hw_lock to cover
all uses of m_is_open, preventing issues.
  • Loading branch information
simonhyde committed Feb 26, 2019
1 parent 90346bc commit af7963e
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions mythtv/libs/libmythtv/recorders/dvbchannel.cpp
Expand Up @@ -108,7 +108,11 @@ DVBChannel::~DVBChannel()
if (!s_master_map[key].empty())
new_master = dynamic_cast<DVBChannel*>(s_master_map[key].front());
if (new_master)
{
QMutexLocker master_locker(&(master->m_hw_lock));
QMutexLocker new_master_locker(&(new_master->m_hw_lock));
new_master->m_is_open = master->m_is_open;
}
}
else
{
Expand All @@ -133,14 +137,14 @@ void DVBChannel::Close(DVBChannel *who)
{
LOG(VB_CHANNEL, LOG_INFO, LOC + "Closing DVB channel");

QMutexLocker locker(&m_hw_lock);

IsOpenMap::iterator it = m_is_open.find(who);
if (it == m_is_open.end())
return; // this caller didn't have it open in the first place..

m_is_open.erase(it);

QMutexLocker locker(&m_hw_lock);

DVBChannel *master = GetMasterLock();
if (master != nullptr && master != this)
{
Expand Down Expand Up @@ -357,6 +361,8 @@ bool DVBChannel::Open(DVBChannel *who)

bool DVBChannel::IsOpen(void) const
{
//Have to acquire the hw lock to prevent is_open being modified whilst we're searching it
QMutexLocker locker(&m_hw_lock);
IsOpenMap::const_iterator it = m_is_open.find(this);
return it != m_is_open.end();
}
Expand Down

0 comments on commit af7963e

Please sign in to comment.