Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.8.0, 5.11.2
-
None
-
d8962144b425b9929770b67bcfb8247a9e9b9022 (qt/qtbase/5.12)
Description
While debugging Qt's failure to load a valid plugin, I discovered that the failure was due to a check made in QElfParser::parse(). When I read the code and compared it with the ELF specification, I saw nothing that required the checked condition, and that the corresponding warning message was inaccurate.
Here's the bad code, starting at line 170/171 of qtbase/src/corelib/plugin/qelfparser_p:
if ((quint32)(m_stringTableFileOffset + e_shentsize) >= fdlen || m_stringTableFileOffset == 0) { if (lib) lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("string table seems to be at %1")) .arg(QString::number(soff, 16)); return Corrupt; }
The string table is at _m_stringTableFileOffset_, not soff, which was copied from the previous check. Also, there seems to be no requirement in the ELF specification that the string table itself has to come at least _e_shentsize_ (the section header size) bytes before the end of the ELF library. The code seems to be intended to check whether the string table section is fully contained within the library file. Here's my modified code that makes the proper check:
if ((quint32)(m_stringTableFileOffset + strtab.size) > fdlen || m_stringTableFileOffset == 0) { if (lib) lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("string table seems to be at %1")) .arg(QString::number(m_stringTableFileOffset, 16)); return Corrupt; }
As for my testing, I ran into the problem on Genode, a platform not officially supported by Qt, but the code should be fixed regardless of whether the symptom can be easily reproduced on a supported platform.
I used multiple versions of my plugin, all compiled and linked with GCC. Version A fails to load unless the library is stripped (with strip, not sstrip), but loads properly when stripped. Version B is the same as version A, except for a minor change in an unimportant function. Version B won't load, even when stripped. All failures give the same error message: "QElfParser: '[_plugin path_]' is an invalid ELF object (string table seems to be at [_shstrtab offset_])"
By the way, I specified Qt 5.8.0 because I discovered the bug with that version, and Qt 5.11.2 because that's the latest release, and the bug is still there.
Attachments
For Gerrit Dashboard: QTBUG-71443 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
243926,3 | Fix calculation of the string tab size in QElfParser | 5.12 | qt/qtbase | Status: MERGED | +2 | 0 |