QElfParser: don't attempt to parse ELF files of the wrong endianness
There's no sense in continuing to parse. We'll never be able to load such a plugin anyway. This simplifies the code generation a lot because now all the read<T> calls become unconditional qFromUnaligned<T>, which is just a memcpy(), which for primitive types the compiler will simply emit a memory load into a register. Task-number: QTBUG-96327 Pick-to: 6.2 Change-Id: I2de1b4dfacd443148279fffd16a3574daf010635 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
a8083ff47a
commit
33a870afae
@ -50,15 +50,15 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
const char *QElfParser::parseSectionHeader(const char *data, ElfSectionHeader *sh)
|
const char *QElfParser::parseSectionHeader(const char *data, ElfSectionHeader *sh)
|
||||||
{
|
{
|
||||||
sh->name = read<qelfword_t>(data);
|
sh->name = qFromUnaligned<qelfword_t>(data);
|
||||||
data += sizeof(qelfword_t); // sh_name
|
data += sizeof(qelfword_t); // sh_name
|
||||||
sh->type = read<qelfword_t>(data);
|
sh->type = qFromUnaligned<qelfword_t>(data);
|
||||||
data += sizeof(qelfword_t) // sh_type
|
data += sizeof(qelfword_t) // sh_type
|
||||||
+ sizeof(qelfaddr_t) // sh_flags
|
+ sizeof(qelfaddr_t) // sh_flags
|
||||||
+ sizeof(qelfaddr_t); // sh_addr
|
+ sizeof(qelfaddr_t); // sh_addr
|
||||||
sh->offset = read<qelfoff_t>(data);
|
sh->offset = qFromUnaligned<qelfoff_t>(data);
|
||||||
data += sizeof(qelfoff_t); // sh_offset
|
data += sizeof(qelfoff_t); // sh_offset
|
||||||
sh->size = read<qelfoff_t>(data);
|
sh->size = qFromUnaligned<qelfoff_t>(data);
|
||||||
data += sizeof(qelfoff_t); // sh_size
|
data += sizeof(qelfoff_t); // sh_size
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -97,13 +97,14 @@ auto QElfParser::parse(const char *dataStart, ulong fdlen, const QString &librar
|
|||||||
lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library, QLibrary::tr("wrong cpu architecture"));
|
lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library, QLibrary::tr("wrong cpu architecture"));
|
||||||
return Corrupt;
|
return Corrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// endian
|
// endian
|
||||||
if (data[5] == 0) {
|
constexpr int ExpectedEndianness = (Q_BYTE_ORDER == Q_LITTLE_ENDIAN) ? 1 : 2;
|
||||||
|
if (data[5] != ExpectedEndianness) {
|
||||||
if (lib)
|
if (lib)
|
||||||
lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library, QLibrary::tr("odd endianness"));
|
lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library, QLibrary::tr("odd endianness"));
|
||||||
return Corrupt;
|
return Corrupt;
|
||||||
}
|
}
|
||||||
m_endian = (data[5] == 1 ? ElfLittleEndian : ElfBigEndian);
|
|
||||||
|
|
||||||
data += 16 // e_ident
|
data += 16 // e_ident
|
||||||
+ sizeof(qelfhalf_t) // e_type
|
+ sizeof(qelfhalf_t) // e_type
|
||||||
@ -112,11 +113,11 @@ auto QElfParser::parse(const char *dataStart, ulong fdlen, const QString &librar
|
|||||||
+ sizeof(qelfaddr_t) // e_entry
|
+ sizeof(qelfaddr_t) // e_entry
|
||||||
+ sizeof(qelfoff_t); // e_phoff
|
+ sizeof(qelfoff_t); // e_phoff
|
||||||
|
|
||||||
qelfoff_t e_shoff = read<qelfoff_t> (data);
|
qelfoff_t e_shoff = qFromUnaligned<qelfoff_t> (data);
|
||||||
data += sizeof(qelfoff_t) // e_shoff
|
data += sizeof(qelfoff_t) // e_shoff
|
||||||
+ sizeof(qelfword_t); // e_flags
|
+ sizeof(qelfword_t); // e_flags
|
||||||
|
|
||||||
qelfhalf_t e_shsize = read<qelfhalf_t> (data);
|
qelfhalf_t e_shsize = qFromUnaligned<qelfhalf_t> (data);
|
||||||
|
|
||||||
if (e_shsize > fdlen) {
|
if (e_shsize > fdlen) {
|
||||||
if (lib)
|
if (lib)
|
||||||
@ -128,7 +129,7 @@ auto QElfParser::parse(const char *dataStart, ulong fdlen, const QString &librar
|
|||||||
+ sizeof(qelfhalf_t) // e_phentsize
|
+ sizeof(qelfhalf_t) // e_phentsize
|
||||||
+ sizeof(qelfhalf_t); // e_phnum
|
+ sizeof(qelfhalf_t); // e_phnum
|
||||||
|
|
||||||
qelfhalf_t e_shentsize = read<qelfhalf_t> (data);
|
qelfhalf_t e_shentsize = qFromUnaligned<qelfhalf_t> (data);
|
||||||
|
|
||||||
if (e_shentsize % 4) {
|
if (e_shentsize % 4) {
|
||||||
if (lib)
|
if (lib)
|
||||||
@ -136,9 +137,9 @@ auto QElfParser::parse(const char *dataStart, ulong fdlen, const QString &librar
|
|||||||
return Corrupt;
|
return Corrupt;
|
||||||
}
|
}
|
||||||
data += sizeof(qelfhalf_t); // e_shentsize
|
data += sizeof(qelfhalf_t); // e_shentsize
|
||||||
qelfhalf_t e_shnum = read<qelfhalf_t> (data);
|
qelfhalf_t e_shnum = qFromUnaligned<qelfhalf_t> (data);
|
||||||
data += sizeof(qelfhalf_t); // e_shnum
|
data += sizeof(qelfhalf_t); // e_shnum
|
||||||
qelfhalf_t e_shtrndx = read<qelfhalf_t> (data);
|
qelfhalf_t e_shtrndx = qFromUnaligned<qelfhalf_t> (data);
|
||||||
data += sizeof(qelfhalf_t); // e_shtrndx
|
data += sizeof(qelfhalf_t); // e_shtrndx
|
||||||
|
|
||||||
if ((quint32)(e_shnum * e_shentsize) > fdlen) {
|
if ((quint32)(e_shnum * e_shentsize) > fdlen) {
|
||||||
|
@ -82,19 +82,9 @@ public:
|
|||||||
qelfoff_t size;
|
qelfoff_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
int m_endian;
|
|
||||||
int m_bits;
|
int m_bits;
|
||||||
qelfoff_t m_stringTableFileOffset;
|
qelfoff_t m_stringTableFileOffset;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T read(const char *s)
|
|
||||||
{
|
|
||||||
if (m_endian == ElfBigEndian)
|
|
||||||
return qFromBigEndian<T>(s);
|
|
||||||
else
|
|
||||||
return qFromLittleEndian<T>(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *parseSectionHeader(const char* s, ElfSectionHeader *sh);
|
const char *parseSectionHeader(const char* s, ElfSectionHeader *sh);
|
||||||
ScanResult parse(const char *m_s, ulong fdlen, const QString &library, QLibraryPrivate *lib, qsizetype *pos, qsizetype *sectionlen);
|
ScanResult parse(const char *m_s, ulong fdlen, const QString &library, QLibraryPrivate *lib, qsizetype *pos, qsizetype *sectionlen);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user