CVE-2015-1038
CVE-2016-9296
---
main/p7zip/APKBUILD | 26 ++--
main/p7zip/CVE-2015-1038.patch | 317 +++++++++++++++++++++++++++++++++++++++++
main/p7zip/CVE-2016-9296.patch | 17 +++
3 files changed, 352 insertions(+), 8 deletions(-)
create mode 100644 main/p7zip/CVE-2015-1038.patch
create mode 100644 main/p7zip/CVE-2016-9296.patch
diff --git a/main/p7zip/APKBUILD b/main/p7zip/APKBUILD
index 8f1a2a5..10c46ef 100644
--- a/main/p7zip/APKBUILD
+++ b/main/p7zip/APKBUILD
@@ -1,7 +1,8 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
+# Contributor: Sergey Lukin <sergej.lukin@gmail.com>
pkgname=p7zip
pkgver=9.20.1
-pkgrel=2
+pkgrel=3
pkgdesc="A command-line port of the 7zip compression utility"
url="http://p7zip.sourceforge.net"
arch="all"
@@ -11,18 +12,21 @@ depends=
makedepends="bash"
#install=p7zip.install
source="http://downloads.sourceforge.net/sourceforge/$pkgname/${pkgname}_${pkgver}_src_all.tar.bz2
- p7zip-cc-cxx.patch"
+ p7zip-cc-cxx.patch
+ CVE-2015-1038.patch
+ CVE-2016-9296.patch
+ "
-_builddir="$srcdir"/${pkgname}_${pkgver}
+builddir="$srcdir"/${pkgname}_${pkgver}
build() {
- cd "$_builddir"
+ cd "$builddir"
patch -p1 -i ../p7zip-cc-cxx.patch || return 1
sed -i "s|usr/local|usr|g" makefile
make all3 OPTFLAGS="${CXXFLAGS}" || return 1
}
package() {
- cd "$_builddir"
+ cd "$builddir"
make install DEST_HOME="$pkgdir"/usr DEST_MAN="$pkgdir"/usr/share/man \
DEST_SHARE_DOC="http://www.bugaco.com/7zip"
@@ -33,8 +37,14 @@ package() {
}
md5sums="bd6caaea567dc0d995c990c5cc883c89 p7zip_9.20.1_src_all.tar.bz2
-8e8f415267bb5db179e4a8ed75985244 p7zip-cc-cxx.patch"
+8e8f415267bb5db179e4a8ed75985244 p7zip-cc-cxx.patch
+7277c65b33493f23e6bed822088f9202 CVE-2015-1038.patch
+8242ea6835b180546a4bf798a94d71bb CVE-2016-9296.patch"
sha256sums="49557e7ffca08100f9fc687f4dfc5aea703ca207640c76d9dee7b66f03cb4782 p7zip_9.20.1_src_all.tar.bz2
-dc77487a62591a4e5ec4ffd2c6340f124295f3b11e2040455deed37c5723660c p7zip-cc-cxx.patch"
+dc77487a62591a4e5ec4ffd2c6340f124295f3b11e2040455deed37c5723660c p7zip-cc-cxx.patch
+0a3071e2d479c455738a9d6d52dc47f92805a0ac021263755af21c3deb96480f CVE-2015-1038.patch
+ff0e104a28ea055a31c78ccb817614e1a2ae252c2e87aab5da4c9ce3fcfcaa44 CVE-2016-9296.patch"
sha512sums="7bb8a276aaefc4a83364e45633c48527de44c6b1205344f3356db570582f30f81d82a94938c99a7ad193587b584cc1c03219c28249de40018bdaee6c3b2a022a p7zip_9.20.1_src_all.tar.bz2
-476f6b5c6b617868afbecc912dcef6bea3dfc7e0476e169bc43d830ef33229bd6895c963f8481f31f897390aa07ed77ec8f02f4e36b2dd8619135d11d28863fa p7zip-cc-cxx.patch"
+476f6b5c6b617868afbecc912dcef6bea3dfc7e0476e169bc43d830ef33229bd6895c963f8481f31f897390aa07ed77ec8f02f4e36b2dd8619135d11d28863fa p7zip-cc-cxx.patch
+121925d618becb9a42818b2d9bfa74869071ce589dfdea8039511d9a5296da40a575bedd88f59c37710007d3381671c67750f023998c3b3b1d892a830d4d6ca2 CVE-2015-1038.patch
+ecb718864aed9c13781ed076de9dea88eea75226d53904cd98ec048d9731843c741403759815964706483f379ef304cb9bb5fca8c1202d580c211ae679607065 CVE-2016-9296.patch"
diff --git a/main/p7zip/CVE-2015-1038.patch b/main/p7zip/CVE-2015-1038.patch
new file mode 100644
index 0000000..1013b73
--- /dev/null
+++ b/main/p7zip/CVE-2015-1038.patch
@@ -0,0 +1,317 @@
+https://sourceforge.net/p/p7zip/bugs/147/
+https://sourceforge.net/p/p7zip/bugs/_discuss/thread/17901103/2f9c/attachment/CVE-2015-1038.patch
+
+Author: Ben Hutchings <ben@decadent.org.uk>
+Date: Tue, 19 May 2015 02:38:40 +0100
+Description: Delay creation of symlinks to prevent arbitrary file writes (CVE-2015-1038)
+Bug-Debian: https://bugs.debian.org/774660
+
+Alexander Cherepanov discovered that 7zip is susceptible to a
+directory traversal vulnerability. While extracting an archive, it
+will extract symlinks and then follow them if they are referenced in
+further entries. This can be exploited by a rogue archive to write
+files outside the current directory.
+
+We have to create placeholder files (which we already do) and delay
+creating symlinks until the end of extraction.
+
+Due to the possibility of anti-items (deletions) in the archive, it is
+possible for placeholders to be deleted and replaced before we create
+the symlinks. It's not clear that this can be used for mischief, but
+GNU tar guards against similar problems by checking that the placeholder
+still exists and is the same inode. XXX It also checks 'birth time' but
+this isn't portable. We can probably get away with comparing ctime
+since we don't support hard links.
+
+--- a/CPP/7zip/UI/Agent/Agent.cpp
++++ b/CPP/7zip/UI/Agent/Agent.cpp
+@@ -424,6 +424,8 @@ STDMETHODIMP CAgentFolder::Extract(const
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+ UStringVector pathParts;
+ CProxyFolder *currentProxyFolder = _proxyFolderItem;
++ HRESULT res;
++
+ while (currentProxyFolder->Parent)
+ {
+ pathParts.Insert(0, currentProxyFolder->Name);
+@@ -445,8 +447,11 @@ STDMETHODIMP CAgentFolder::Extract(const
+ (UInt64)(Int64)-1);
+ CUIntVector realIndices;
+ GetRealIndices(indices, numItems, realIndices);
+- return _agentSpec->GetArchive()->Extract(&realIndices.Front(),
++ res = _agentSpec->GetArchive()->Extract(&realIndices.Front(),
+ realIndices.Size(), testMode, extractCallback);
++ if (res == S_OK && !extractCallbackSpec->CreateSymLinks())
++ res = E_FAIL;
++ return res;
+ COM_TRY_END
+ }
+
+--- a/CPP/7zip/UI/Agent/ArchiveFolder.cpp
++++ b/CPP/7zip/UI/Agent/ArchiveFolder.cpp
+@@ -20,6 +20,8 @@ STDMETHODIMP CAgentFolder::CopyTo(const
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+ UStringVector pathParts;
+ CProxyFolder *currentProxyFolder = _proxyFolderItem;
++ HRESULT res;
++
+ while (currentProxyFolder->Parent)
+ {
+ pathParts.Insert(0, currentProxyFolder->Name);
+@@ -46,8 +48,11 @@ STDMETHODIMP CAgentFolder::CopyTo(const
+ (UInt64)(Int64)-1);
+ CUIntVector realIndices;
+ GetRealIndices(indices, numItems, realIndices);
+- return _agentSpec->GetArchive()->Extract(&realIndices.Front(),
++ res = _agentSpec->GetArchive()->Extract(&realIndices.Front(),
+ realIndices.Size(), BoolToInt(false), extractCallback);
++ if (res == S_OK && !extractCallbackSpec->CreateSymLinks())
++ res = E_FAIL;
++ return res;
+ COM_TRY_END
+ }
+
+--- a/CPP/7zip/UI/Client7z/Client7z.cpp
++++ b/CPP/7zip/UI/Client7z/Client7z.cpp
+@@ -197,8 +197,11 @@ private:
+ COutFileStream *_outFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outFileStream;
+
++ CObjectVector<NWindows::NFile::NDirectory::CDelayedSymLink> _delayedSymLinks;
++
+ public:
+ void Init(IInArchive *archiveHandler, const UString &directoryPath);
++ bool CreateSymLinks();
+
+ UInt64 NumErrors;
+ bool PasswordIsDefined;
+@@ -392,11 +395,22 @@ STDMETHODIMP CArchiveExtractCallback::Se
+ }
+ _outFileStream.Release();
+ if (_extractMode && _processedFileInfo.AttribDefined)
+- NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attrib);
++ NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attrib, &_delayedSymLinks);
+ PrintNewLine();
+ return S_OK;
+ }
+
++bool CArchiveExtractCallback::CreateSymLinks()
++{
++ bool success = true;
++
++ for (int i = 0; i != _delayedSymLinks.Size(); ++i)
++ success &= _delayedSymLinks[i].Create();
++
++ _delayedSymLinks.Clear();
++
++ return success;
++}
+
+ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
+ {
+--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
++++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
+@@ -453,12 +453,24 @@ STDMETHODIMP CArchiveExtractCallback::Se
+ NumFiles++;
+
+ if (_extractMode && _fi.AttribDefined)
+- NFile::NDirectory::MySetFileAttributes(_diskFilePath, _fi.Attrib);
++ NFile::NDirectory::MySetFileAttributes(_diskFilePath, _fi.Attrib, &_delayedSymLinks);
+ RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted));
+ return S_OK;
+ COM_TRY_END
+ }
+
++bool CArchiveExtractCallback::CreateSymLinks()
++{
++ bool success = true;
++
++ for (int i = 0; i != _delayedSymLinks.Size(); ++i)
++ success &= _delayedSymLinks[i].Create();
++
++ _delayedSymLinks.Clear();
++
++ return success;
++}
++
+ /*
+ STDMETHODIMP CArchiveExtractCallback::GetInStream(
+ const wchar_t *name, ISequentialInStream **inStream)
+--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.h
++++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
+@@ -6,6 +6,8 @@
+ #include "Common/MyCom.h"
+ #include "Common/Wildcard.h"
+
++#include "Windows/FileDir.h"
++
+ #include "../../IPassword.h"
+
+ #include "../../Common/FileStreams.h"
+@@ -83,6 +85,8 @@ class CArchiveExtractCallback:
+ UInt64 _packTotal;
+ UInt64 _unpTotal;
+
++ CObjectVector<NWindows::NFile::NDirectory::CDelayedSymLink> _delayedSymLinks;
++
+ void CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath);
+ HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
+ HRESULT GetUnpackSize();
+@@ -138,6 +142,7 @@ public:
+ const UStringVector &removePathParts,
+ UInt64 packSize);
+
++ bool CreateSymLinks();
+ };
+
+ #endif
+--- a/CPP/7zip/UI/Common/Extract.cpp
++++ b/CPP/7zip/UI/Common/Extract.cpp
+@@ -96,6 +96,9 @@ static HRESULT DecompressArchive(
+ else
+ result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec);
+
++ if (result == S_OK && !extractCallbackSpec->CreateSymLinks())
++ result = E_FAIL;
++
+ return callback->ExtractResult(result);
+ }
+
+--- a/CPP/Windows/FileDir.cpp
++++ b/CPP/Windows/FileDir.cpp
+@@ -453,9 +453,10 @@ bool SetDirTime(LPCWSTR fileName, const
+ }
+
+ #ifndef _UNICODE
+-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
++bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes,
++ CObjectVector<CDelayedSymLink> *delayedSymLinks)
+ {
+- return MySetFileAttributes(UnicodeStringToMultiByte(fileName, CP_ACP), fileAttributes);
++ return MySetFileAttributes(UnicodeStringToMultiByte(fileName, CP_ACP), fileAttributes, delayedSymLinks);
+ }
+
+ bool MyRemoveDirectory(LPCWSTR pathName)
+@@ -488,7 +489,8 @@ static int convert_to_symlink(const char
+ return -1;
+ }
+
+-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
++bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes,
++ CObjectVector<CDelayedSymLink> *delayedSymLinks)
+ {
+ if (!fileName) {
+ SetLastError(ERROR_PATH_NOT_FOUND);
+@@ -520,7 +522,9 @@ bool MySetFileAttributes(LPCTSTR fileNam
+ stat_info.st_mode = fileAttributes >> 16;
+ #ifdef ENV_HAVE_LSTAT
+ if (S_ISLNK(stat_info.st_mode)) {
+- if ( convert_to_symlink(name) != 0) {
++ if (delayedSymLinks)
++ delayedSymLinks->Add(CDelayedSymLink(name));
++ else if ( convert_to_symlink(name) != 0) {
+ TRACEN((printf("MySetFileAttributes(%s,%d) : false-3\n",name,fileAttributes)))
+ return false;
+ }
+@@ -924,4 +928,41 @@ bool CTempDirectory::Create(LPCTSTR pref
+ }
+
+
++#ifdef ENV_UNIX
++
++CDelayedSymLink::CDelayedSymLink(LPCSTR source)
++ : _source(source)
++{
++ struct stat st;
++
++ if (lstat(_source, &st) == 0) {
++ _dev = st.st_dev;
++ _ino = st.st_ino;
++ } else {
++ _dev = 0;
++ }
++}
++
++bool CDelayedSymLink::Create()
++{
++ struct stat st;
++
++ if (_dev == 0) {
++ errno = EPERM;
++ return false;
++ }
++ if (lstat(_source, &st) != 0)
++ return false;
++ if (_dev != st.st_dev || _ino != st.st_ino) {
++ // Placeholder file has been overwritten or moved by another
++ // symbolic link creation
++ errno = EPERM;
++ return false;
++ }
++
++ return convert_to_symlink(_source) == 0;
++}
++
++#endif // ENV_UNIX
++
+ }}}
+--- a/CPP/Windows/FileDir.h
++++ b/CPP/Windows/FileDir.h
+@@ -4,6 +4,7 @@
+ #define __WINDOWS_FILEDIR_H
+
+ #include "../Common/MyString.h"
++#include "../Common/MyVector.h"
+ #include "Defs.h"
+
+ /* GetFullPathName for 7zAES.cpp */
+@@ -13,11 +14,15 @@ namespace NWindows {
+ namespace NFile {
+ namespace NDirectory {
+
++class CDelayedSymLink;
++
+ bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
+
+-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes);
++bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes,
++ CObjectVector<CDelayedSymLink> *delayedSymLinks = 0);
+ #ifndef _UNICODE
+-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes);
++bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes,
++ CObjectVector<CDelayedSymLink> *delayedSymLinks = 0);
+ #endif
+
+ bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName);
+@@ -80,6 +85,31 @@ public:
+ bool Remove();
+ };
+
++// Symbolic links must be created last so that they can't be used to
++// create or overwrite files above the extraction directory.
++class CDelayedSymLink
++{
++#ifdef ENV_UNIX
++ // Where the symlink should be created. The target is specified in
++ // the placeholder file.
++ AString _source;
++
++ // Device and inode of the placeholder file. Before creating the
++ // symlink, we must check that these haven't been changed by creation
++ // of another symlink.
++ dev_t _dev;
++ ino_t _ino;
++
++public:
++ explicit CDelayedSymLink(LPCSTR source);
++ bool Create();
++#else // !ENV_UNIX
++public:
++ CDelayedSymLink(LPCSTR source) {}
++ bool Create() { return true; }
++#endif // ENV_UNIX
++};
++
+ #ifdef _UNICODE
+ typedef CTempFile CTempFileW;
+ #endif
diff --git a/main/p7zip/CVE-2016-9296.patch b/main/p7zip/CVE-2016-9296.patch
new file mode 100644
index 0000000..06c4c45
--- /dev/null
+++ b/main/p7zip/CVE-2016-9296.patch
@@ -0,0 +1,17 @@
+CVE-2016-9296
+https://sourceforge.net/p/p7zip/bugs/185/
+https://sourceforge.net/p/p7zip/discussion/383043/thread/648d34db/
+
+
+--- p7zip_9.38.1.orig/CPP/7zip/Archive/7z/7zIn.cpp
++++ p7zip_9.38.1/CPP/7zip/Archive/7z/7zIn.cpp
+@@ -1142,7 +1142,8 @@
+ if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
+ ThrowIncorrect();
+ }
+- HeadersSize += folders.PackPositions[folders.NumPackStreams];
++ if (folders.PackPositions) //this line is fixing CVE-2016-9296 (https://sourceforge.net/p/p7zip/bugs/185, https://sourceforge.net/p/p7zip/discussion/383043/thread/648d34db/?limit=25#d9d7)
++ HeadersSize += folders.PackPositions[folders.NumPackStreams];
+ return S_OK;
+ }
+
--
2.2.1
---
Unsubscribe: alpine-aports+unsubscribe@lists.alpinelinux.org
Help: alpine-aports+help@lists.alpinelinux.org
---