[sword-devel] Major Sword bug found -- buffer overflow

Troy A. Griffitts scribe at crosswire.org
Thu Mar 2 10:34:48 MST 2006


Hey guys,
	Sadly, we've known about this since we implemented cipher support. 
There may be a bug in sapphire, as DM points out, but here's the real 
problem:

	To implement cipher support more securely, we have no way to know if 
the user has entered a correct key.

	Consider why.  If there was a confirmation of the correct key, then 
anyone could brute force all the unlock keys fairly easily.  As it 
stands now, if they have the correct key, they see correct text, 
otherwise, they see jibberish.

	The major problem is that most of our filters don't do a good job with 
invalid markup (consider jibberish can have <>[] and other meta characters).

	So, now how do we protect against the situation which Martin points out:

	A user has a locked module installed and has entered an invalid key.


	Granted, a good first step is to make our filters' error handling more 
robust-- which could never be a bad thing, done without optization hits.

	Other suggestions are most welcomed.

		-Troy.



Martin Gruner wrote:
> Hi,
> 
> sorry for my misunderstanding of how Sword internals work.
> 
> However, the problem is there, it may be something in the decompression 
> algorithm. I'm attaching a valgrind trace of the crash in BibleTime when I 
> try to open the GerHfaLex2002 without a valid key.
> 
> mg
> 
> --
> 
> no room in outbuffer to during decompression. see zipcomp.cpp
> ==6598==
> ==6598== Conditional jump or move depends on uninitialised value(s)
> ==6598==    at 0x599FD16: sword::EntriesBlock::getMetaEntry(int, unsigned 
> long*, unsigned long*) (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599FFC7: sword::EntriesBlock::getEntrySize(int) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599EBDA: sword::zStr::getCompressedText(long, long, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599FB28: sword::zStr::getText(long, char**, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0644: sword::zLD::getEntry(long) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F08DF: sword::zLD::getRawEntryBuf() 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59EEC61: sword::SWLD::setPosition(sword::SW_POSITION) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x812B19E: CSwordLexiconModuleInfo::entries() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80ACF99: CLexiconKeyChooser::refreshContent() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80AD702: 
> CLexiconKeyChooser::CLexiconKeyChooser(QValueList<CSwordModuleInfo*>, 
> CSwordKey*, QWidget*, char const*) 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80A45FE: 
> CKeyChooser::createInstance(QValueList<CSwordModuleInfo*>, CSwordKey*, 
> QWidget*) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x808785B: CLexiconReadWindow::initView() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==
> ==6598== Conditional jump or move depends on uninitialised value(s)
> ==6598==    at 0x599FD16: sword::EntriesBlock::getMetaEntry(int, unsigned 
> long*, unsigned long*) (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599FF78: sword::EntriesBlock::getEntry(int) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599EC0F: sword::zStr::getCompressedText(long, long, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599FB28: sword::zStr::getText(long, char**, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0644: sword::zLD::getEntry(long) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F08DF: sword::zLD::getRawEntryBuf() 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59EEC61: sword::SWLD::setPosition(sword::SW_POSITION) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x812B19E: CSwordLexiconModuleInfo::entries() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80ACF99: CLexiconKeyChooser::refreshContent() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80AD702: 
> CLexiconKeyChooser::CLexiconKeyChooser(QValueList<CSwordModuleInfo*>, 
> CSwordKey*, QWidget*, char const*) 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80A45FE: 
> CKeyChooser::createInstance(QValueList<CSwordModuleInfo*>, CSwordKey*, 
> QWidget*) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x808785B: CLexiconReadWindow::initView() 
> (in /home/dev/bibletime/bibletime/bibletime)
> no room in outbuffer to during decompression. see zipcomp.cpp
> ==6598==
> ==6598== Conditional jump or move depends on uninitialised value(s)
> ==6598==    at 0x599FFD0: sword::EntriesBlock::getEntrySize(int) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599EBDA: sword::zStr::getCompressedText(long, long, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599FB28: sword::zStr::getText(long, char**, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0644: sword::zLD::getEntry(long) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0824: sword::zLD::increment(int) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x812B263: CSwordLexiconModuleInfo::entries() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80ACF99: CLexiconKeyChooser::refreshContent() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80AD702: 
> CLexiconKeyChooser::CLexiconKeyChooser(QValueList<CSwordModuleInfo*>, 
> CSwordKey*, QWidget*, char const*) 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80A45FE: 
> CKeyChooser::createInstance(QValueList<CSwordModuleInfo*>, CSwordKey*, 
> QWidget*) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x808785B: CLexiconReadWindow::initView() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80868AE: CDisplayWindow::init() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x807E11E: 
> BibleTime::createReadDisplayWindow(QValueList<CSwordModuleInfo*>, QString 
> const&) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==
> ==6598== Conditional jump or move depends on uninitialised value(s)
> ==6598==    at 0x599FF81: sword::EntriesBlock::getEntry(int) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599EC0F: sword::zStr::getCompressedText(long, long, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599FB28: sword::zStr::getText(long, char**, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0644: sword::zLD::getEntry(long) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0824: sword::zLD::increment(int) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x812B263: CSwordLexiconModuleInfo::entries() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80ACF99: CLexiconKeyChooser::refreshContent() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80AD702: 
> CLexiconKeyChooser::CLexiconKeyChooser(QValueList<CSwordModuleInfo*>, 
> CSwordKey*, QWidget*, char const*) 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80A45FE: 
> CKeyChooser::createInstance(QValueList<CSwordModuleInfo*>, CSwordKey*, 
> QWidget*) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x808785B: CLexiconReadWindow::initView() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80868AE: CDisplayWindow::init() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x807E11E: 
> BibleTime::createReadDisplayWindow(QValueList<CSwordModuleInfo*>, QString 
> const&) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==
> ==6598== Conditional jump or move depends on uninitialised value(s)
> ==6598==    at 0x401D917: realloc (vg_replace_malloc.c:306)
> ==6598==    by 0x599EBF7: sword::zStr::getCompressedText(long, long, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599FB28: sword::zStr::getText(long, char**, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0644: sword::zLD::getEntry(long) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0824: sword::zLD::increment(int) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x812B263: CSwordLexiconModuleInfo::entries() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80ACF99: CLexiconKeyChooser::refreshContent() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80AD702: 
> CLexiconKeyChooser::CLexiconKeyChooser(QValueList<CSwordModuleInfo*>, 
> CSwordKey*, QWidget*, char const*) 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80A45FE: 
> CKeyChooser::createInstance(QValueList<CSwordModuleInfo*>, CSwordKey*, 
> QWidget*) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x808785B: CLexiconReadWindow::initView() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80868AE: CDisplayWindow::init() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x807E11E: 
> BibleTime::createReadDisplayWindow(QValueList<CSwordModuleInfo*>, QString 
> const&) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==
> ==6598== Use of uninitialised value of size 4
> ==6598==    at 0x401E7AA: strcpy (mac_replace_strmem.c:269)
> ==6598==    by 0x599EC1D: sword::zStr::getCompressedText(long, long, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599FB28: sword::zStr::getText(long, char**, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0644: sword::zLD::getEntry(long) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0824: sword::zLD::increment(int) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x812B263: CSwordLexiconModuleInfo::entries() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80ACF99: CLexiconKeyChooser::refreshContent() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80AD702: 
> CLexiconKeyChooser::CLexiconKeyChooser(QValueList<CSwordModuleInfo*>, 
> CSwordKey*, QWidget*, char const*) 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80A45FE: 
> CKeyChooser::createInstance(QValueList<CSwordModuleInfo*>, CSwordKey*, 
> QWidget*) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x808785B: CLexiconReadWindow::initView() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80868AE: CDisplayWindow::init() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x807E11E: 
> BibleTime::createReadDisplayWindow(QValueList<CSwordModuleInfo*>, QString 
> const&) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==
> ==6598== Conditional jump or move depends on uninitialised value(s)
> ==6598==    at 0x401E7B3: strcpy (mac_replace_strmem.c:269)
> ==6598==    by 0x599EC1D: sword::zStr::getCompressedText(long, long, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599FB28: sword::zStr::getText(long, char**, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0644: sword::zLD::getEntry(long) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0824: sword::zLD::increment(int) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x812B263: CSwordLexiconModuleInfo::entries() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80ACF99: CLexiconKeyChooser::refreshContent() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80AD702: 
> CLexiconKeyChooser::CLexiconKeyChooser(QValueList<CSwordModuleInfo*>, 
> CSwordKey*, QWidget*, char const*) 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80A45FE: 
> CKeyChooser::createInstance(QValueList<CSwordModuleInfo*>, CSwordKey*, 
> QWidget*) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x808785B: CLexiconReadWindow::initView() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80868AE: CDisplayWindow::init() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x807E11E: 
> BibleTime::createReadDisplayWindow(QValueList<CSwordModuleInfo*>, QString 
> const&) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==
> ==6598== Conditional jump or move depends on uninitialised value(s)
> ==6598==    at 0x401E7DC: strcpy (mac_replace_strmem.c:69)
> ==6598==    by 0x599EC1D: sword::zStr::getCompressedText(long, long, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599FB28: sword::zStr::getText(long, char**, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0644: sword::zLD::getEntry(long) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0824: sword::zLD::increment(int) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x812B263: CSwordLexiconModuleInfo::entries() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80ACF99: CLexiconKeyChooser::refreshContent() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80AD702: 
> CLexiconKeyChooser::CLexiconKeyChooser(QValueList<CSwordModuleInfo*>, 
> CSwordKey*, QWidget*, char const*) 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80A45FE: 
> CKeyChooser::createInstance(QValueList<CSwordModuleInfo*>, CSwordKey*, 
> QWidget*) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x808785B: CLexiconReadWindow::initView() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80868AE: CDisplayWindow::init() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x807E11E: 
> BibleTime::createReadDisplayWindow(QValueList<CSwordModuleInfo*>, QString 
> const&) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598== Warning: set address range perms: large range 243302452, a 0, v 1
> ==6598== Warning: set address range perms: large range 243302481, a 1, v 1
> ==6598== Warning: silly arg (-2147483639) to realloc()
> ==6598==
> ==6598== Invalid write of size 1
> ==6598==    at 0x401E7C0: strcpy (mac_replace_strmem.c:269)
> ==6598==    by 0x599EC1D: sword::zStr::getCompressedText(long, long, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x599FB28: sword::zStr::getText(long, char**, char**) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0644: sword::zLD::getEntry(long) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x59F0824: sword::zLD::increment(int) 
> (in /usr/lib/libsword.so.5.0.0)
> ==6598==    by 0x812B263: CSwordLexiconModuleInfo::entries() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80ACF99: CLexiconKeyChooser::refreshContent() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80AD702: 
> CLexiconKeyChooser::CLexiconKeyChooser(QValueList<CSwordModuleInfo*>, 
> CSwordKey*, QWidget*, char const*) 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80A45FE: 
> CKeyChooser::createInstance(QValueList<CSwordModuleInfo*>, CSwordKey*, 
> QWidget*) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x808785B: CLexiconReadWindow::initView() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x80868AE: CDisplayWindow::init() 
> (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==    by 0x807E11E: 
> BibleTime::createReadDisplayWindow(QValueList<CSwordModuleInfo*>, QString 
> const&) (in /home/dev/bibletime/bibletime/bibletime)
> ==6598==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
> *** BibleTime got signal 11 (Crashing). Trying to save settings.
> _______________________________________________
> sword-devel mailing list: sword-devel at crosswire.org
> http://www.crosswire.org/mailman/listinfo/sword-devel
> Instructions to unsubscribe/change your settings at above page



More information about the sword-devel mailing list