GNOME Bugzilla – Bug 340624
Segfault during shutdown of more than one extension modules
Last modified: 2006-05-11 13:04:46 UTC
A segfault occurs during shutdown of extension modules if there are more than 1 modules registered. Scenario: Assume the hash table style->extInfos contains 2 entries: 1) style->extInfos->table[9] is a valid entry 2) style->extInfos->table[9]->next is also a valid entry Callstack: ... --> xsltShutdownExts() Iterates over the entries of style->extInfos --> xmlHashScan(style->extInfos, (xmlHashScanner) xsltShutdownExt, style); --> xmlHashScanFull() --> stubHashScannerFull --> xsltShutdownExt(): While iterating over the table's entries, the current entry is removed: xmlHashRemoveEntry(style->extInfos, URI, (xmlHashDeallocator) xsltFreeExtData); --> xmlHashRemoveEntry() --> xmlHashRemoveEntry3(): The memory of $entry->next is moved to the position of $entry. The old $entry is freed. entry = entry->next; memcpy(&(table->table[key]), entry, sizeof(xmlHashEntry)); xmlFree(entry); ... --> back in xmlHashScanFull(): We have here: while (iter) { next = iter->next; if ((f != NULL) && (iter->payload != NULL)) f(iter->payload, data, iter->name, iter->name2, iter->name3); iter = next; } Since $next was set to $iter->next, which was freed in xmlHashRemoveEntry3(), the $iter will point to stale memory. The next execution of the callback "f", which is the xsltShutdownExt(), will produce the segfault due to the corrupt data.
I tried to simply eliminate the removal of hash entries in xsltShutdownExt(). This seems to work fine. It follows also now the semantic of the related xsltShutdownCtxtExt(). xsltShutdownExt() is a static function called only by xsltShutdownExts(), so there won't be a side-effect of this modification. In xsltShutdownExts() the cleanup of the whole hash table entries is performed anyway.
Fixed in CVS, extensions.c, revision 1.41.