Fix use-after-free because QByteArray::data() was copying data

Previously there was a mixture of buf.constData() and buf.data() with
buf not being const QByteArray. As a result, buf.data() returned a
re-allocated buffer and texData was keeping pointers to that one, which
became invalid once the function returned and the re-allocated buffer
was cleaned up by destructor.

Change buf to const QByteArray so that there is no difference between
data() and constData(). Additionally convert all constData() calls to
data() to avoid confusion.

Detected by Address Sanitizer on testcase
  tst_qtexturefilereader::checkMetadata()

Pick-to: 6.3 6.2
Change-Id: Idb6f6141898678bf95ed9233a92b7bb3ad12e250
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
This commit is contained in:
Dimitrios Apostolou 2022-04-09 00:06:22 +02:00
parent f9f1085735
commit b8677bd31f

View File

@ -126,14 +126,14 @@ QTextureFileData QKtxHandler::read()
if (!device())
return QTextureFileData();
QByteArray buf = device()->readAll();
const QByteArray buf = device()->readAll();
const quint32 dataSize = quint32(buf.size());
if (dataSize < headerSize || !canRead(QByteArray(), buf)) {
qCDebug(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData());
return QTextureFileData();
}
const KTXHeader *header = reinterpret_cast<const KTXHeader *>(buf.constData());
const KTXHeader *header = reinterpret_cast<const KTXHeader *>(buf.data());
if (!checkHeader(*header)) {
qCDebug(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData());
return QTextureFileData();
@ -162,7 +162,7 @@ QTextureFileData QKtxHandler::read()
if (offset + sizeof(quint32) > dataSize) // Corrupt file; avoid oob read
break;
const quint32 imageSize = decode(qFromUnaligned<quint32>(buf.constData() + offset));
const quint32 imageSize = decode(qFromUnaligned<quint32>(buf.data() + offset));
offset += sizeof(quint32);
for (int face = 0; face < qMin(texData.numFaces(), MAX_ITERATIONS); face++) {