diff --git a/CVE-2023-52168-and-CVE-2023-52169.patch b/CVE-2023-52168-and-CVE-2023-52169.patch new file mode 100644 index 0000000000000000000000000000000000000000..8e5a73236516f86090fb805ea2a47713f22f5dfa --- /dev/null +++ b/CVE-2023-52168-and-CVE-2023-52169.patch @@ -0,0 +1,146 @@ +From: YOKOTA Hiroshi +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 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 --git a/p7zip.spec b/p7zip.spec index f4700e639fb015fe1a11fef794fbf9620a7f7fc9..91422fe371523e6ab65212e10adfb32ee6d5bea3 100644 --- a/p7zip.spec +++ b/p7zip.spec @@ -1,6 +1,6 @@ Name: p7zip Version: 16.02 -Release: 6 +Release: 7 Summary: 7z for Linux system License: LGPLv2 and (LGPLv2+ or CPL) URL: https://sourceforge.net/projects/p7zip/ @@ -11,6 +11,7 @@ Patch2: CVE-2018-5996.patch Patch3: CVE-2018-10115.patch Patch4: fix-build-failed-with-gcc-10.patch Patch5: 0001-add-PIE-compiler-options.patch +Patch6: CVE-2023-52168-and-CVE-2023-52169.patch BuildRequires: gcc-c++ @@ -42,6 +43,9 @@ install -m 0644 man1/7za.1 %{buildroot}/%{_mandir}/man1 %{_mandir}/* %changelog +* Fri Jul 04 2025 yaoxin <1024769339@qq.com> - 16.02-7 +- Fix CVE-2023-52168 and CVE-2023-52169 + * Sat Aug 31 2024 Funda Wang - 16.02-6 - use correct build flags