View Issue Details

IDProjectCategoryView StatusLast Update
0004357ScribusGeneralpublic2006-10-14 21:48
Reporterkili Assigned Tocbradney  
PrioritynormalSeveritycrashReproducibilityalways
Status closedResolutionfixed 
Platformx86OSOpenBSDOS VersionOpenBSD-4.0
Product Version1.3.3.4 
Fixed in Version1.3.3.5cvs 
Summary0004357: Use after free(3) -- segfault after closing and reopening the same document
DescriptionWhen 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 ReproduceNote: 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 InformationIn 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
TagsNo tags attached.
Patch

Activities

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;
patch-scribus_scribus_cpp.2 (640 bytes)   

kili

2006-10-08 16:29

reporter   ~0012850

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.

Issue History

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