7-Zip 16.00で特定のexeファイルを展開しようとした際にクラッシュするという情報がsourceforgeのフォーラムで報告されていたので気になって調べてみた。
7-Zip / Discussion / Open Discussion:7-zip 16.00 64-bit crash
現象
https://downloadmirror.intel.com/10884/a08/INF_allOS_9.1.2.1008_PV.exeを開くと16.00の64-bit版のみEXCEPTION_ACCESS_VIOLATION (c0000005) の例外が発生する。
[code]
アプリケーション名: 7zFM.exe
アプリケーションのバージョン: 16.0.0.0
アプリケーションのタイムスタンプ: 5731aa47
障害モジュールの名前: 7z.dll
障害モジュールのバージョン: 16.0.0.0
障害モジュールのタイムスタンプ: 5731aba0
例外コード: c0000005
例外オフセット: 0000000000040713
[/code]
一つ前のバージョンである15.04の64-bit版ではクラッシュせずに展開できる。
32-bit版では「要求された量のメモリを割り当てることができません」というメッセージが表示されて開くことができないが、クラッシュはしない。
原因
CPP/7zip/Archive/PeHandler.cppの変更が原因であることがわかった。
PEファイルのリソースセクションの処理で、
セクションのVirtualSize(VSize)とSizeOfRawData(PSize)の小さいほうのサイズで確保されたバッファに対して、バッファの走査を行う際の境界判定の箇所のみSizeOfRawData(PSize)に変えたことが原因。
これによって、VirtualSize(VSize)よりSizeOfRawData(PSize)が大きいリソースセクションを持つPEファイル(exe)を開いた際にクラッシュする場合がある。
該当行は以下の画像を参照。
修正
バッファの領域外の参照が原因であり、特に危険な脆弱性ということはないと思われるので本家の修正を待てばよいと思う。
ただし、16.00には2件の脆弱性修正も含まれているため古いバージョンを使用するべきではない。
一応、以下のパッチを当て、ビルドするとクラッシュしなくなることは確認できた。
[code]
— PeHandler.cpp 2016-01-14 16:49:31.000000000 +0900
+++ PeHandler_fix.cpp 2016-05-16 01:50:01.000000000 +0900
@@ -1898,7 +1898,7 @@ static bool ParseVersion(const Byte *p,
HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback)
{
const CSection § = _sections[sectionIndex];
– const size_t fileSize = sect.GetSizeMin();
+ const size_t fileSize = sect.GetSizeExtract();
if (fileSize > kFileSizeMax)
return S_FALSE;
[/code]
※ 上記パッチの使用は自己責任でお願いします。パッチ自体のライセンスはパブリックドメイン扱いで。
コメント