From 7b2976d92c83139b25a73b705b6d57b836f4bdd1 Mon Sep 17 00:00:00 2001 From: Nikolaj Schlej Date: Wed, 9 Apr 2014 18:29:12 +0200 Subject: [PATCH] Version 0.17.6 - corrected extended firmware volume header handling - corrected a rare crash on trying to decompress EFI11-compressed sections with TianoDecompress routine --- Tiano/EfiTianoDecompress.c | 14 +++++++++++--- ffsengine.cpp | 15 +++++++++++++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Tiano/EfiTianoDecompress.c b/Tiano/EfiTianoDecompress.c index 62002e3..7fac2fe 100644 --- a/Tiano/EfiTianoDecompress.c +++ b/Tiano/EfiTianoDecompress.c @@ -255,10 +255,14 @@ for (Char = 0; Char < NumOfChar; Char++) { NextCode = (UINT16) (Start[Len] + Weight[Len]); - if (Len <= TableBits) { + if (Len <= TableBits) { for (Index = Start[Len]; Index < NextCode; Index++) { - Table[Index] = Char; + // Check to prevent possible heap corruption + if (Index >= (UINT16) (1U << TableBits)) + return (UINT16)BAD_TABLE; + + Table[Index] = Char; } } else { @@ -643,7 +647,11 @@ for (;;) { BytesRemain = CharC; DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1; - + if (DataIdx >= Sd->mOrigSize) { + Sd->mBadTableFlag = 1; + return; + } + BytesRemain--; while ((INT16) (BytesRemain) >= 0) { Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++]; diff --git a/ffsengine.cpp b/ffsengine.cpp index b8eed55..179ff82 100644 --- a/ffsengine.cpp +++ b/ffsengine.cpp @@ -671,13 +671,16 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, co // Calculate volume header size UINT32 headerSize; if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) { - EFI_FIRMWARE_VOLUME_EXT_HEADER* extendedHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)((UINT8*)volumeHeader + volumeHeader->ExtHeaderOffset); + EFI_FIRMWARE_VOLUME_EXT_HEADER* extendedHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(volume.constData() + volumeHeader->ExtHeaderOffset); headerSize = volumeHeader->ExtHeaderOffset + extendedHeader->ExtHeaderSize; } else { headerSize = volumeHeader->HeaderLength; } + // Sanity check after some new crazy MSI images + headerSize = ALIGN8(headerSize); + // Check for volume structure to be known // Default volume subtype is "normal" UINT8 subtype = Subtypes::NormalVolume; @@ -737,7 +740,14 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, co .arg(volumeSize, 8, 16, QChar('0')) .arg(volumeHeader->Revision) .arg(volumeHeader->Attributes, 8, 16, QChar('0')) - .arg(volumeHeader->HeaderLength, 4, 16, QChar('0')); + .arg(headerSize, 4, 16, QChar('0')); + // Extended header present + if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) { + EFI_FIRMWARE_VOLUME_EXT_HEADER* extendedHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(volume.constData() + volumeHeader->ExtHeaderOffset); + info += tr("\nExtended header size: %1\nVolume name: %2") + .arg(extendedHeader->ExtHeaderSize, 8, 16, QChar('0')) + .arg(guidToQString(extendedHeader->FvName)); + } // Add tree item QByteArray header = volume.left(headerSize); @@ -1685,6 +1695,7 @@ UINT8 FfsEngine::decompress(const QByteArray & compressedData, const UINT8 compr scratch = new UINT8[scratchSize]; // Decompress section data + //TODO: separate EFI1.1 from Tiano another way // Try Tiano decompression first if (ERR_SUCCESS != TianoDecompress(data, dataSize, decompressed, decompressedSize, scratch, scratchSize)) { // Not Tiano, try EFI 1.1