From patchwork Thu Nov 30 02:04:37 2006 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Udo Richter X-Patchwork-Id: 12410 Received: from mail.gmx.net ([213.165.64.20]) by www.linuxtv.org with smtp (Exim 4.50) id 1GpbJ4-0006c9-Lv for vdr@linuxtv.org; Thu, 30 Nov 2006 03:05:46 +0100 Received: (qmail invoked by alias); 30 Nov 2006 02:05:16 -0000 Received: from p57A8A1E1.dip0.t-ipconnect.de (EHLO localhost) [87.168.161.225] by mail.gmx.net (mp020) with SMTP; 30 Nov 2006 03:05:16 +0100 X-Authenticated: #1417946 Message-ID: <456E3C35.5080708@gmx.de> Date: Thu, 30 Nov 2006 03:04:37 +0100 From: Udo Richter User-Agent: Thunderbird 2.0b1pre (Windows/20061127) MIME-Version: 1.0 To: VDR Mailing List X-Y-GMX-Trusted: 0 Subject: [vdr] Segfault if cSkinDisplayMessage is replaced by another display object X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Nov 2006 02:05:46 -0000 Status: O X-Status: X-Keywords: X-UID: 11289 Hi Klaus, I've isolated an null pointer dereferencing bug in cSkins::Message(): In the very rare case that a message is displayed using a cSkinDisplayMessage object, and the message is not removed before another cSkinDisplay object takes control, the next attempt to display a message while no cSkinDisplay::Current() object is available causes a segfault. The reason is that the cSkins::displayMessage pointer is not cleared if another cSkinDisplay object takes over. cSkins::Message() sees an existing displayMessage object, but accesses the non-existing cSkinDisplay::Current(), assuming they're both the same. The only way I know how to trigger this is to use mtStatus messages and allow user activity while the message is shown. I don't think that plain VDR can trigger this on its own. The attached patch changes cSkins::Message() by only checking the existence of cSkinDisplay::Current(). If no current cSkinDisplay exists, any old displayMessage object is deleted and a new one is created. Cheers, Udo --- skins.c.orig 2006-11-30 02:19:41.705523304 +0100 +++ skins.c 2006-11-30 02:33:28.269230960 +0100 @@ -226,8 +226,11 @@ } if (!Current()) return kNone; - if (!cSkinDisplay::Current() && !displayMessage) + if (!cSkinDisplay::Current()) { + if (displayMessage) + delete displayMessage; displayMessage = Current()->DisplayMessage(); + } cSkinDisplay::Current()->SetMessage(Type, s); cSkinDisplay::Current()->Flush(); cStatus::MsgOsdStatusMessage(s);