View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0004357 | Scribus | General | public | 2006-10-04 21:43 | 2006-10-14 21:48 |
Reporter | kili | Assigned To | cbradney | ||
Priority | normal | Severity | crash | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Platform | x86 | OS | OpenBSD | OS Version | OpenBSD-4.0 |
Product Version | 1.3.3.4 | ||||
Fixed in Version | 1.3.3.5cvs | ||||
Summary | 0004357: Use after free(3) -- segfault after closing and reopening the same document | ||||
Description | When using Open Recent on a document opened and closed in the same session earlier, scribus crashes due to access to memory already free(3)d. | ||||
Steps To Reproduce | Note: on systems other than OpenBSD you may need some malloc-debugging toolkits to reproduce this. - Start scribus, create an empty document, save it, exit scribus. - Start scribus, Open Recent on the previously created empty document. - Close the document (without exiting), Open Recent the same document. => segfault. | ||||
Additional Information | In ScribusMainWindow::DoFileClose(), the nodePalette's doc isn't reset in all cases, only when doc->EditClip is true. It seems that this isn't always the case when closing a document (for whatever reason). The attached patch tries to fix this by resetting the nodePalette's doc at the very end of ScribusMainWindow::DoFileClose(), right before the delete doc, iff both doc (that of ScribusMainWindow and that of nodePalette) are equal. Please note that this patch may break other things, especially the undomanager, so don't accept it blindly. BTW, the patch also replaces the conditional call of ToggleFrameEdit() to NoFrameEdit() -- I found the former a little bit confusing, since the same conditional (doc->EditClip) is checked for in ToggleFrameEdit(). Here's the matching gdb traceback: (gdb) run Starting program: /usr/local/bin/scribus Program received signal SIGSEGV, Segmentation fault. [Switching to process 18538, thread 0x848f3000] 0x1c42e882 in ScribusDoc::unitRatio() const (this=0x7d2a6000) at scribusdoc.cpp:1948 1948 return docUnitRatio; (gdb) print *this Cannot access memory at address 0x7d2a6028 (gdb) where #0 0x1c42e882 in ScribusDoc::unitRatio() const (this=0x7d2a6000) at scribusdoc.cpp:1948 0000001 0x1c20691e in NodePalette::unitChange() (this=0x8184a000) at frameedit.cpp:753 0000002 0x1c5c1f8e in ScribusMainWindow::slotChangeUnit(int, bool) (this=0x7f53f000, unitIndex=0, draw=true) at scribus.cpp:7536 0000003 0x1c596f3b in ScribusMainWindow::HaveNewDoc() (this=0x7f53f000) at scribus.cpp:2355 0000004 0x1c5a0c97 in ScribusMainWindow::loadDoc(QString) (this=0x7f53f000, fileName= {static null = {static null = <same as static member of an already seen type>, d = 0x7cf2a440, static shared_null = 0x7cf2a440}, d = 0x828dc1e0, static shared_null = 0x7cf2a440}) at scribus.cpp:3512 0000005 0x1c59dfb6 in ScribusMainWindow::loadRecent(QString) (this=0x7f53f000, fn= {static null = {static null = <same as static member of an already seen type>, d = 0x7cf2a440, static shared_null = 0x7cf2a440}, d = 0x828dc1e0, static shared_null = 0x7cf2a440}) at scribus.cpp:2966 0000006 0x1c57eab3 in ScribusMainWindow::qt_invoke(int, QUObject*) (this=0x7f53f000, _id=-813930064, _o=0x7c426130) at qucom_p.h:449 0000007 0x02a9c3ae in QObject::activate_signal(QConnectionList*, QUObject*) () from /usr/local/lib/libqt-mt.so.30.0 0000008 0x02a9c84b in QObject::activate_signal(int, QString) () from /usr/local/lib/libqt-mt.so.30.0 0000009 0x1c411d44 in ScrAction::activatedData(QString) (this=0x7da8b980) at qmetaobject.h:261 0000010 0x1c412a45 in ScrAction::activatedToActivatedData() (this=0x7da8b980) at scraction.cpp:123 0000011 0x1c41216d in ScrAction::qt_invoke(int, QUObject*) (this=0x7da8b980, _id=15, _o=0xcf7c6bd0) at scraction.moc:208 0000012 0x02a9c3ae in QObject::activate_signal(QConnectionList*, QUObject*) () from /usr/local/lib/libqt-mt.so.30.0 0000013 0x02a9c1dd in QObject::activate_signal(int) () from /usr/local/lib/libqt-mt.so.30.0 0000014 0x02d9f0dc in QAction::activated() () from /usr/local/lib/libqt-mt.so.30.0 0000015 0x02bc14b6 in QAction::internalActivation() () from /usr/local/lib/libqt-mt.so.30.0 0000016 0x02d9f1e0 in QAction::qt_invoke(int, QUObject*) () from /usr/local/lib/libqt-mt.so.30.0 0000017 0x1c41212d in ScrAction::qt_invoke(int, QUObject*) (this=0x7da8b980, _id=8, _o=0xcf7c6d40) at scraction.moc:211 0000018 0x02a9c3ae in QObject::activate_signal(QConnectionList*, QUObject*) () from /usr/local/lib/libqt-mt.so.30.0 0000019 0x02d84e46 in QSignal::signal(QVariant const&) () from /usr/local/lib/libqt-mt.so.30.0 0000020 0x02ab2aa8 in QSignal::activate() () from /usr/local/lib/libqt-mt.so.30.0 0000021 0x02b8b7cf in QPopupMenu::mouseReleaseEvent(QMouseEvent*) () from /usr/local/lib/libqt-mt.so.30.0 0000022 0x02acc06e in QWidget::event(QEvent*) () from /usr/local/lib/libqt-mt.so.30.0 0000023 0x02a48241 in QApplication::internalNotify(QObject*, QEvent*) () from /usr/local/lib/libqt-mt.so.30.0 0000024 0x02a477d6 in QApplication::notify(QObject*, QEvent*) () from /usr/local/lib/libqt-mt.so.30.0 0000025 0x029e6ea7 in QETWidget::translateMouseEvent(_XEvent const*) () from /usr/local/lib/libqt-mt.so.30.0 0000026 0x029e505c in QApplication::x11ProcessEvent(_XEvent*) () from /usr/local/lib/libqt-mt.so.30.0 0000027 0x029fa92d in QEventLoop::processEvents(unsigned) () from /usr/local/lib/libqt-mt.so.30.0 0000028 0x02a5804b in QEventLoop::enterLoop() () from /usr/local/lib/libqt-mt.so.30.0 0000029 0x02a57f10 in QEventLoop::exec() () from /usr/local/lib/libqt-mt.so.30.0 0000030 0x02a4843c in QApplication::exec() () from /usr/local/lib/libqt-mt.so.30.0 0000031 0x1c5d005b in mainApp(int, char**) (argc=1, argv=0xcf7c76dc) at main_nix.cpp:74 0000032 0x1c5cffdf in main (argc=1, argv=0xcf7c76dc) at main_nix.cpp:50 (gdb) up 0000001 0x1c20691e in NodePalette::unitChange() (this=0x8184a000) at frameedit.cpp:753 753 unitRatio = doc->unitRatio(); (gdb) print doc $1 = (class ScribusDoc *) 0x7d2a6000 (gdb) up 0000002 0x1c5c1f8e in ScribusMainWindow::slotChangeUnit(int, bool) (this=0x7f53f000, unitIndex=0, draw=true) at scribus.cpp:7536 7536 nodePalette->unitChange(); (gdb) print doc $2 = (class ScribusDoc *) 0x7c414000 | ||||
Tags | No tags attached. | ||||
Patch | |||||
2006-10-04 21:43
|
patch-scribus_scribus_cpp.2 (640 bytes)
$OpenBSD$ --- scribus/scribus.cpp.orig Mon Oct 2 01:08:04 2006 +++ scribus/scribus.cpp Tue Oct 3 19:40:26 2006 @@ -3988,10 +3988,7 @@ bool ScribusMainWindow::DoFileClose() // if (doc->EditClip) // nodePalette->doc = 0; if (doc->EditClip) - { - ToggleFrameEdit(); - nodePalette->setDoc(0,0); - } + NoFrameEdit(); bookmarkPalette->BView->clear(); bookmarkPalette->BView->NrItems = 0; @@ -4074,6 +4071,8 @@ bool ScribusMainWindow::DoFileClose() fileWatcher->removeFile(fName); HaveDoc--; view = NULL; + if (nodePalette->currentDocument() == doc) + nodePalette->setDoc(0, 0); delete doc; doc = NULL; ActWin = NULL; |
|
Update for CVS Version133x (1.3.3.5cvs): same problem, the deleted doc still happily sits within the nodePalette. Here's the output when letting it run to the end (i.e. coredump): Scribus Crash ------------- Scribus crashes due to Signal 0000011 Calling Emergency Save scribus in free(): error: chunk is already free Abort trap (core dumped) gdb session typescript: [kili@petunia:kili]$ gdb /usr/local/bin/scribus GNU gdb 6.3 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-unknown-openbsd4.0"... (gdb) break scribus.cpp:4074 Breakpoint 1 at 0x1c5a781a: file scribus.cpp, line 4074. (gdb) break scribus.cpp:3990 Breakpoint 2 at 0x1c5a7640: file scribus.cpp, line 3990. (gdb) run Starting program: /usr/local/bin/scribus [Switching to process 9604, thread 0x86b80000] Breakpoint 2, ScribusMainWindow::DoFileClose() (this=0x7f2dd000) at scribus.cpp:3990 3990 if (doc->EditClip) (gdb) print doc $1 = (class ScribusDoc *) 0x7d120000 (gdb) print doc->EditClip $2 = false (gdb) cont Continuing. Breakpoint 1, ScribusMainWindow::DoFileClose() (this=0x7f2dd000) at scribus.cpp:4074 4074 delete doc; (gdb) print doc $3 = (class ScribusDoc *) 0x7d120000 (gdb) print doc->EditClip $4 = false (gdb) print nodePalette $5 = (class NodePalette *) 0x7de97000 (gdb) print nodePalette->doc $6 = (class ScribusDoc *) 0x7d120000 (gdb) cont Continuing. Program received signal SIGSEGV, Segmentation fault. 0x1c42ffda in ScribusDoc::unitRatio() const (this=0x7d120000) at scribusdoc.cpp:1948 1948 return docUnitRatio; (gdb) where #0 0x1c42ffda in ScribusDoc::unitRatio() const (this=0x7d120000) at scribusdoc.cpp:1948 0000001 0x1c20695a in NodePalette::unitChange() (this=0x7de97000) at frameedit.cpp:753 0000002 0x1c5c374e in ScribusMainWindow::slotChangeUnit(int, bool) (this=0x7f2dd000, unitIndex=0, draw=true) at scribus.cpp:7533 0000003 0x1c59870b in ScribusMainWindow::HaveNewDoc() (this=0x7f2dd000) at scribus.cpp:2355 0000004 0x1c5a2467 in ScribusMainWindow::loadDoc(QString) (this=0x7f2dd000, fileName= {static null = {static null = <same as static member of an already seen type>, d = 0x869f6440, static shared_null = 0x869f6440}, d = 0x85d1be40, static shared_null = 0x869f6440}) at scribus.cpp:3512 0000005 0x1c59f786 in ScribusMainWindow::loadRecent(QString) (this=0x7f2dd000, fn= {static null = {static null = <same as static member of an already seen type>, d = 0x869f6440, static shared_null = 0x869f6440}, d = 0x85d1be40, static shared_null = 0x869f6440}) at scribus.cpp:2966 0000006 0x1c580283 in ScribusMainWindow::qt_invoke(int, QUObject*) (this=0x7f2dd000, _id=-813708992, _o=0x7d125ca0) at qucom_p.h:449 0000007 0x00e293ae in QObject::activate_signal(QConnectionList*, QUObject*) () from /usr/local/lib/libqt-mt.so.30.0 0000008 0x00e2984b in QObject::activate_signal(int, QString) () from /usr/local/lib/libqt-mt.so.30.0 0000009 0x1c41349c in ScrAction::activatedData(QString) (this=0x81489b00) at qmetaobject.h:261 0000010 0x1c41419d in ScrAction::activatedToActivatedData() (this=0x81489b00) at scraction.cpp:123 0000011 0x1c4138c5 in ScrAction::qt_invoke(int, QUObject*) (this=0x81489b00, _id=15, _o=0xcf7fcb60) at scraction.moc:208 0000012 0x00e293ae in QObject::activate_signal(QConnectionList*, QUObject*) () from /usr/local/lib/libqt-mt.so.30.0 0000013 0x00e291dd in QObject::activate_signal(int) () from /usr/local/lib/libqt-mt.so.30.0 0000014 0x0112c0dc in QAction::activated() () from /usr/local/lib/libqt-mt.so.30.0 0000015 0x00f4e4b6 in QAction::internalActivation() () from /usr/local/lib/libqt-mt.so.30.0 0000016 0x0112c1e0 in QAction::qt_invoke(int, QUObject*) () from /usr/local/lib/libqt-mt.so.30.0 0000017 0x1c413885 in ScrAction::qt_invoke(int, QUObject*) (this=0x81489b00, _id=8, _o=0xcf7fccd0) at scraction.moc:211 0000018 0x00e293ae in QObject::activate_signal(QConnectionList*, QUObject*) () from /usr/local/lib/libqt-mt.so.30.0 0000019 0x01111e46 in QSignal::signal(QVariant const&) () from /usr/local/lib/libqt-mt.so.30.0 0000020 0x00e3faa8 in QSignal::activate() () from /usr/local/lib/libqt-mt.so.30.0 0000021 0x00f187cf in QPopupMenu::mouseReleaseEvent(QMouseEvent*) () from /usr/local/lib/libqt-mt.so.30.0 0000022 0x00e5906e in QWidget::event(QEvent*) () from /usr/local/lib/libqt-mt.so.30.0 0000023 0x00dd5241 in QApplication::internalNotify(QObject*, QEvent*) () from /usr/local/lib/libqt-mt.so.30.0 0000024 0x00dd47d6 in QApplication::notify(QObject*, QEvent*) () from /usr/local/lib/libqt-mt.so.30.0 0000025 0x00d73ea7 in QETWidget::translateMouseEvent(_XEvent const*) () from /usr/local/lib/libqt-mt.so.30.0 0000026 0x00d7205c in QApplication::x11ProcessEvent(_XEvent*) () from /usr/local/lib/libqt-mt.so.30.0 0000027 0x00d8792d in QEventLoop::processEvents(unsigned) () from /usr/local/lib/libqt-mt.so.30.0 0000028 0x00de504b in QEventLoop::enterLoop() () from /usr/local/lib/libqt-mt.so.30.0 0000029 0x00de4f10 in QEventLoop::exec() () from /usr/local/lib/libqt-mt.so.30.0 0000030 0x00dd543c in QApplication::exec() () from /usr/local/lib/libqt-mt.so.30.0 0000031 0x1c5d181b in mainApp(int, char**) (argc=1, argv=0xcf7fd678) at main_nix.cpp:74 0000032 0x1c5d179f in main (argc=1, argv=0xcf7fd678) at main_nix.cpp:50 (gdb) up 0000001 0x1c20695a in NodePalette::unitChange() (this=0x7de97000) at frameedit.cpp:753 753 unitRatio = doc->unitRatio(); (gdb) up 0000002 0x1c5c374e in ScribusMainWindow::slotChangeUnit(int, bool) (this=0x7f2dd000, unitIndex=0, draw=true) at scribus.cpp:7533 7533 nodePalette->unitChange(); (gdb) print doc $7 = (class ScribusDoc *) 0x7ecb5000 (gdb) # i.e. different doc, but nodePalette still has the old (deleted) one. |
Date Modified | Username | Field | Change |
---|---|---|---|
2006-10-04 21:43 | kili | New Issue | |
2006-10-04 21:43 | kili | File Added: patch-scribus_scribus_cpp.2 | |
2006-10-04 22:31 | cbradney | Status | new => assigned |
2006-10-04 22:31 | cbradney | Assigned To | => cbradney |
2006-10-08 16:29 | kili | Note Added: 0012850 | |
2006-10-08 20:07 | cbradney | Status | assigned => resolved |
2006-10-08 20:07 | cbradney | Fixed in Version | => 1.3.3.5cvs |
2006-10-08 20:07 | cbradney | Resolution | open => fixed |
2006-10-14 21:48 | cbradney | Status | resolved => closed |