X-Original-To: alpine-aports@lists.alpinelinux.org Received: from mail-wj0-f195.google.com (mail-wj0-f195.google.com [209.85.210.195]) by lists.alpinelinux.org (Postfix) with ESMTP id 1DBB15C4591 for ; Mon, 12 Dec 2016 16:50:09 +0000 (GMT) Received: by mail-wj0-f195.google.com with SMTP id xy5so12461634wjc.1 for ; Mon, 12 Dec 2016 08:50:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=ZsUtjddOosC5kkVUro2BQpqkrvqY0M5kDag1rw5NeUQ=; b=TRCODBnjIyc8pPx1jSBMS2tLKUhEFLZDhWWzEe42Jvx3R0veY2MzX9I5zyYbM7sOuK FMd6ey5zklFWbdkr+m/aSb2cSf0V3w1hA9kkOJGgVskRs7dr3So9YNFQgSHADOz0Zzxw kEE8CxVg4NJ7JfqU2EgMA4ByJwPt7nx8P2nhtlBnfwH8vBU0QQz2rkPQjFQpFBWaUEug TgS0tKWKLvADEWcBDEGZfcUA6o5P3Xr+/WB7hgwRLGzVyqMXQU+NiZzVH3Eokq2rvTXb 0G0g9A+mE7M5pUqxZzK3OXN8jjim+ZVQFWtFZc+Tj2I7uBv0amOV+BWL5+ik3llb2zV6 6pDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=ZsUtjddOosC5kkVUro2BQpqkrvqY0M5kDag1rw5NeUQ=; b=cP9s7+IOZ8BgedFTNMW5Re/A8Tn4kFMbglKOqJKi/36lVKQVap0+xRCQFD4D0hhjyg 9WoeNm+Wc8fiW4hhPynGHpX54IBrJ6unkoZtmoB+WXy8+DaIc1ek0chBwlq4GRfcSNv3 9OEWLftiqYZPkA/HfVCeAiU/0ZSKXgxzrAvu7XlfR/NW3lLBIo4bGfVPxw1kXn5YlUaZ Y+cH44XeW6PtHM8R+Jq4j8wu1SdwEcT3NM3xgNEamXBB8dWsc63r6aNALMrKPe6/OW8o B5B0DLtUIasfQXCIsYHiqIZVzmNlhpgsCI13DXj51G3xLG4T5h0oIbZ+Qkjs8rBUoiej fzog== X-Gm-Message-State: AKaTC03tae6B4aKLcfHe9ef4k7BdTpgBCDwtCJAHiHCTo71b6mjxEC3N+TDqPMDOcUNWEA== X-Received: by 10.46.7.18 with SMTP id 18mr10347723ljh.30.1481546750459; Mon, 12 Dec 2016 04:45:50 -0800 (PST) Received: from v3-1.util.wtbts.net ([83.145.235.199]) by smtp.gmail.com with ESMTPSA id z2sm9031558lja.10.2016.12.12.04.45.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 12 Dec 2016 04:45:49 -0800 (PST) From: Sergey Lukin To: alpine-aports@lists.alpinelinux.org Cc: Sergey Lukin Subject: [alpine-aports] [PATCH v3.1] main/p7zip: security upgrade - fixes #3831 Date: Mon, 12 Dec 2016 12:45:42 +0000 Message-Id: <1481546742-11867-1-git-send-email-sergej.lukin@gmail.com> X-Mailer: git-send-email 2.2.1 X-Mailinglist: alpine-aports Precedence: list List-Id: Alpine Development List-Unsubscribe: List-Post: List-Help: List-Subscribe: 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 +# Contributor: Sergey Lukin 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 +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 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 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 _outFileStream; + ++ CObjectVector _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 _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 *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 *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 *delayedSymLinks = 0); + #ifndef _UNICODE +-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes); ++bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes, ++ CObjectVector *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 ---