Package: release.debian.org Severity: normal Tags: bookworm security X-Debbugs-Cc: 7...@packages.debian.org, t...@security.debian.org, yokota.h...@gmail.com Control: affects -1 + src:7zip User: release.debian....@packages.debian.org Usertags: pu
[ Reason ] Fix CVE-2023-52168 (buffer overflow) and CVE-2023-52169 (buffer over-read) [ Impact ] Some vulnerabilities are unfixed. [ Tests ] Very trivial NTFS disk image file test was passed. * list files * extract files [ Risks ] Upstream dose not provide fix patch. So I extract fix patch from CVE reporter's blog entry. > https://dfir.ru/2024/06/19/vulnerabilities-in-7-zip-and-ntfs3/ I think the fix patch will works, but not confirmed by upstream because upstream dose not provides fix patch files. [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable [ Changes ] Add fix-ups to NTFS extractor. [ Other info ] CVE Reporter's blog entry: > https://dfir.ru/2024/06/19/vulnerabilities-in-7-zip-and-ntfs3/ Debdiff can be examine from online: > https://salsa.debian.org/debian/7zip/-/tree/bookworm-update > https://salsa.debian.org/debian/7zip/-/commits/33950db8e8c9130ac6718fde10515c74f9c6cecc Roger Shimizu <r...@debian.org> provides bookworm-backports package 7zip:24.08+dfsg-1~bpo12+1. 7zip 24.08 already fixed the vulnerabilities by upstream since 24.05. -- YOKOTA Hiroshi
diff -Nru 7zip-22.01+dfsg/debian/changelog 7zip-22.01+dfsg/debian/changelog --- 7zip-22.01+dfsg/debian/changelog 2022-12-18 21:09:42.000000000 +0900 +++ 7zip-22.01+dfsg/debian/changelog 2024-10-06 11:40:03.000000000 +0900 @@ -1,3 +1,9 @@ +7zip (22.01+dfsg-8+deb12u1) bookworm; urgency=medium + + * Fix CVE-2023-52168 and CVE-2023-52169 + + -- YOKOTA Hiroshi <yokota.h...@gmail.com> Sun, 06 Oct 2024 11:40:03 +0900 + 7zip (22.01+dfsg-8) unstable; urgency=medium * Upgrade Debian standards diff -Nru 7zip-22.01+dfsg/debian/patches/0009-Fix-CVE-2023-52168-and-CVE-2023-52169.patch 7zip-22.01+dfsg/debian/patches/0009-Fix-CVE-2023-52168-and-CVE-2023-52169.patch --- 7zip-22.01+dfsg/debian/patches/0009-Fix-CVE-2023-52168-and-CVE-2023-52169.patch 1970-01-01 09:00:00.000000000 +0900 +++ 7zip-22.01+dfsg/debian/patches/0009-Fix-CVE-2023-52168-and-CVE-2023-52169.patch 2024-10-06 11:40:03.000000000 +0900 @@ -0,0 +1,146 @@ +From: YOKOTA Hiroshi <yokota.h...@gmail.com> +Date: Wed, 2 Oct 2024 12:09:49 +0900 +Subject: Fix CVE-2023-52168 and CVE-2023-52169 + +Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2023-52168 +Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2023-52169 +Forwarded: not-needed + +This patch was extracted from reporter's blog and +upstream/23.01..upstream/24.05 diff. +> https://dfir.ru/2024/06/19/vulnerabilities-in-7-zip-and-ntfs3/ +--- + CPP/7zip/Archive/NtfsHandler.cpp | 89 +++++++++++++++++++++++++--------------- + 1 file changed, 57 insertions(+), 32 deletions(-) + +diff --git a/CPP/7zip/Archive/NtfsHandler.cpp b/CPP/7zip/Archive/NtfsHandler.cpp +index 0b9ee29..39a1299 100755 +--- a/CPP/7zip/Archive/NtfsHandler.cpp ++++ b/CPP/7zip/Archive/NtfsHandler.cpp +@@ -71,6 +71,7 @@ struct CHeader + { + unsigned SectorSizeLog; + unsigned ClusterSizeLog; ++ unsigned MftRecordSizeLog; + // Byte MediaType; + UInt32 NumHiddenSectors; + UInt64 NumSectors; +@@ -156,14 +157,47 @@ bool CHeader::Parse(const Byte *p) + + NumClusters = NumSectors >> sectorsPerClusterLog; + +- G64(p + 0x30, MftCluster); ++ G64(p + 0x30, MftCluster); // $MFT. + // G64(p + 0x38, Mft2Cluster); +- G64(p + 0x48, SerialNumber); +- UInt32 numClustersInMftRec; +- UInt32 numClustersInIndexBlock; +- G32(p + 0x40, numClustersInMftRec); // -10 means 2 ^10 = 1024 bytes. +- G32(p + 0x44, numClustersInIndexBlock); +- return (numClustersInMftRec < 256 && numClustersInIndexBlock < 256); ++ G64(p + 0x48, SerialNumber); // $MFTMirr ++ ++ /* ++ numClusters_per_MftRecord: ++ numClusters_per_IndexBlock: ++ only low byte from 4 bytes is used. Another 3 high bytes are zeros. ++ If the number is positive (number < 0x80), ++ then it represents the number of clusters. ++ If the number is negative (number >= 0x80), ++ then the size of the file record is 2 raised to the absolute value of this number. ++ example: (0xF6 == -10) means 2^10 = 1024 bytes. ++ */ ++ { ++ UInt32 numClusters_per_MftRecord; ++ G32(p + 0x40, numClusters_per_MftRecord); ++ if (numClusters_per_MftRecord >= 0x100 || numClusters_per_MftRecord == 0) ++ return false; ++ if (numClusters_per_MftRecord < 0x80) ++ { ++ const int t = GetLog(numClusters_per_MftRecord); ++ if (t < 0) ++ return false; ++ MftRecordSizeLog = (unsigned)t + ClusterSizeLog; ++ } ++ else ++ MftRecordSizeLog = 0x100 - numClusters_per_MftRecord; ++ // what exact MFT record sizes are possible and supported by Windows? ++ // do we need to change this limit here? ++ const unsigned k_MftRecordSizeLog_MAX = 12; ++ if (MftRecordSizeLog > k_MftRecordSizeLog_MAX) ++ return false; ++ if (MftRecordSizeLog < SectorSizeLog) ++ return false; ++ } ++ { ++ UInt32 numClusters_per_IndexBlock; ++ G32(p + 0x44, numClusters_per_IndexBlock); ++ return (numClusters_per_IndexBlock < 0x100); ++ } + } + + struct CMftRef +@@ -266,8 +300,8 @@ bool CFileNameAttr::Parse(const Byte *p, unsigned size) + G32(p + 0x38, Attrib); + // G16(p + 0x3C, PackedEaSize); + NameType = p[0x41]; +- unsigned len = p[0x40]; +- if (0x42 + len > size) ++ const unsigned len = p[0x40]; ++ if (0x42 + len * 2 > size) + return false; + if (len != 0) + GetString(p + 0x42, len, Name); +@@ -1730,26 +1764,22 @@ HRESULT CDatabase::Open() + + SeekToCluster(Header.MftCluster); + +- CMftRec mftRec; +- UInt32 numSectorsInRec; +- ++ // we use ByteBuf for records reading. ++ // so the size of ByteBuf must be >= mftRecordSize ++ const size_t recSize = (size_t)1 << Header.MftRecordSizeLog; ++ const size_t kBufSize = MyMax((size_t)(1 << 15), recSize); ++ ByteBuf.Alloc(kBufSize); ++ RINOK(ReadStream_FALSE(InStream, ByteBuf, recSize)) ++ { ++ const UInt32 allocSize = Get32(ByteBuf + 0x1C); ++ if (allocSize != recSize) ++ return S_FALSE; ++ } ++ // MftRecordSizeLog >= SectorSizeLog ++ const UInt32 numSectorsInRec = 1u << (Header.MftRecordSizeLog - Header.SectorSizeLog); + CMyComPtr<IInStream> mftStream; ++ CMftRec mftRec; + { +- UInt32 blockSize = 1 << 12; +- ByteBuf.Alloc(blockSize); +- RINOK(ReadStream_FALSE(InStream, ByteBuf, blockSize)); +- +- { +- UInt32 allocSize = Get32(ByteBuf + 0x1C); +- int t = GetLog(allocSize); +- if (t < (int)Header.SectorSizeLog) +- return S_FALSE; +- RecSizeLog = t; +- if (RecSizeLog > 15) +- return S_FALSE; +- } +- +- numSectorsInRec = 1 << (RecSizeLog - Header.SectorSizeLog); + if (!mftRec.Parse(ByteBuf, Header.SectorSizeLog, numSectorsInRec, 0, NULL)) + return S_FALSE; + if (!mftRec.IsFILE()) +@@ -1768,11 +1798,6 @@ HRESULT CDatabase::Open() + if ((mftSize >> 4) > Header.GetPhySize_Clusters()) + return S_FALSE; + +- const size_t kBufSize = (1 << 15); +- const size_t recSize = ((size_t)1 << RecSizeLog); +- if (kBufSize < recSize) +- return S_FALSE; +- + { + const UInt64 numFiles = mftSize >> RecSizeLog; + if (numFiles > (1 << 30)) diff -Nru 7zip-22.01+dfsg/debian/patches/series 7zip-22.01+dfsg/debian/patches/series --- 7zip-22.01+dfsg/debian/patches/series 2022-12-18 21:09:42.000000000 +0900 +++ 7zip-22.01+dfsg/debian/patches/series 2024-10-06 11:40:03.000000000 +0900 @@ -6,3 +6,4 @@ 0006-Disable-local-echo-display-when-in-input-passwords-C.patch 0007-Manually-de-reference-pointers.patch 0008-Remove-unwanted-hack-for-object-files.patch +0009-Fix-CVE-2023-52168-and-CVE-2023-52169.patch