From 5b4541b5ccdb28543b9a2995a20f1c84a262e006 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 11 May 2018 22:13:26 +0200 Subject: [PATCH] pvr/CGUIWindowPVRBase: check m_channelGroup before dereferencing it Fixes several nullptr dereference bugs which could occur after the VNSI connection was closed by VDR, e.g.: ``` Program terminated with signal SIGSEGV, Segmentation fault. #0 __GI___pthread_mutex_lock (mutex=0xf0) at ../nptl/pthread_mutex_lock.c:65 65 ../nptl/pthread_mutex_lock.c: No such file or directory. [Current thread is 1 (Thread 0x7fabcc406980 (LWP 686))] (gdb) bt #0 __GI___pthread_mutex_lock (mutex=0xf0) at ../nptl/pthread_mutex_lock.c:65 #1 0x000055afd0fd788c in (anonymous namespace)::CRecursiveMutex::lock (this=0xf0) at xbmc/threads/platform/RecursiveMutex.h:45 #2 0x000055afd0fd8978 in (anonymous namespace)::CountingLockable::lock (this=0xf0) at xbmc/threads/Lockables.h:63 #3 0x000055afd0fd87c6 in (anonymous namespace)::UniqueLock::UniqueLock (this=0x7ffd221f0450, lockable=...) at xbmc/threads/Lockables.h:132 #4 0x000055afd0ff3fed in CSingleLock::CSingleLock (this=0x7ffd221f0450, cs=...) at xbmc/threads/SingleLock.h:39 #5 0x000055afd1bc6147 in PVR::CPVRChannelGroup::GroupName (this=0x0) at xbmc/pvr/channels/PVRChannelGroup.cpp:1142 #6 0x000055afd1b31555 in PVR::CGUIWindowPVRBase::UpdateButtons (this=0x55afd6d030b0) at xbmc/pvr/windows/GUIWindowPVRBase.cpp:480 #7 0x000055afd1b39898 in PVR::CGUIWindowPVRRecordingsBase::UpdateButtons (this=0x55afd6d030b0) at xbmc/pvr/windows/GUIWindowPVRRecordings.cpp:187 #8 0x000055afd1459dc7 in CGUIMediaWindow::Update (this=0x55afd6d030b0, strDirectory=..., updateFilterPath=true) at xbmc/windows/GUIMediaWindow.cpp:905 ``` --- xbmc/pvr/windows/GUIWindowPVRBase.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.cpp b/xbmc/pvr/windows/GUIWindowPVRBase.cpp index a190e65ce796a..20bc64687c98b 100644 --- a/xbmc/pvr/windows/GUIWindowPVRBase.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRBase.cpp @@ -194,8 +194,10 @@ bool CGUIWindowPVRBase::OnAction(const CAction &action) case ACTION_NEXT_CHANNELGROUP: { // switch to next or previous group - const CPVRChannelGroupPtr channelGroup = GetChannelGroup(); - SetChannelGroup(action.GetID() == ACTION_NEXT_CHANNELGROUP ? channelGroup->GetNextGroup() : channelGroup->GetPreviousGroup()); + if (const CPVRChannelGroupPtr channelGroup = GetChannelGroup()) + { + SetChannelGroup(action.GetID() == ACTION_NEXT_CHANNELGROUP ? channelGroup->GetNextGroup() : channelGroup->GetPreviousGroup()); + } return true; } case ACTION_MOVE_RIGHT: @@ -377,7 +379,10 @@ bool CGUIWindowPVRBase::OpenChannelGroupSelectionDialog(void) dialog->SetHeading(CVariant{g_localizeStrings.Get(19146)}); dialog->SetItems(options); dialog->SetMultiSelection(false); - dialog->SetSelected(GetChannelGroup()->GroupName()); + if (const CPVRChannelGroupPtr channelGroup = GetChannelGroup()) + { + dialog->SetSelected(channelGroup->GroupName()); + } dialog->Open(); if (!dialog->IsConfirmed()) @@ -480,7 +485,11 @@ void CGUIWindowPVRBase::UpdateButtons(void) CGUIMediaWindow::UpdateButtons(); const CPVRChannelGroupPtr channelGroup = GetChannelGroup(); - SET_CONTROL_LABEL(CONTROL_BTNCHANNELGROUPS, g_localizeStrings.Get(19141) + ": " + channelGroup->GroupName()); + if (channelGroup) + { + SET_CONTROL_LABEL(CONTROL_BTNCHANNELGROUPS, g_localizeStrings.Get(19141) + ": " + channelGroup->GroupName()); + } + m_channelGroupsSelector->SelectChannelGroup(channelGroup); }