system/p7zip: Add security patches.

CVE-2015-1038
CVE-2016-2335.

Signed-off-by: Willy Sudiarto Raharjo <willysr@slackbuilds.org>
This commit is contained in:
Sebastien BALLET 2016-06-01 07:41:44 +07:00 committed by Willy Sudiarto Raharjo
parent a3356a2231
commit 6962798555
No known key found for this signature in database
GPG key ID: 887B8374D7333381
3 changed files with 327 additions and 3 deletions

View file

@ -0,0 +1,292 @@
--- 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

View file

@ -0,0 +1,17 @@
Index: p7zip_15.14.1/CPP/7zip/Archive/Udf/UdfIn.cpp
===================================================================
--- p7zip_15.14.1.orig/CPP/7zip/Archive/Udf/UdfIn.cpp
+++ p7zip_15.14.1/CPP/7zip/Archive/Udf/UdfIn.cpp
@@ -389,7 +389,11 @@ HRESULT CInArchive::ReadFileItem(int vol
return S_FALSE;
CFile &file = Files.Back();
const CLogVol &vol = LogVols[volIndex];
- CPartition &partition = Partitions[vol.PartitionMaps[lad.Location.PartitionRef].PartitionIndex];
+ unsigned partitionRef = lad.Location.PartitionRef;
+
+ if (partitionRef >= vol.PartitionMaps.Size())
+ return S_FALSE;
+ CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex];
UInt32 key = lad.Location.Pos;
UInt32 value;

View file

@ -23,8 +23,8 @@
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
PRGNAM=p7zip
VERSION=9.20.1
BUILD=${BUILD:-1}
VERSION=${VERSION:-9.20.1}
BUILD=${BUILD:-2}
TAG=${TAG:-_SBo}
if [ -z "$ARCH" ]; then
@ -70,7 +70,22 @@ find -L . \
\( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
-o -perm 511 \) -exec chmod 755 {} \; -o \
\( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
-o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
-o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
# patch to fix security issues :
#
# CVE-2015-1038:
# p7zip 9.20.1 allows remote attackers to write to arbitrary files via a symlink attack in an archive.
# https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1038
# https://sourceforge.net/p/p7zip/bugs/147/#2f9c
#
# CVE-2016-2335:
# 7zip UDF CInArchive::ReadFileItem Code Execution Vulnerability
# http://www.talosintel.com/reports/TALOS-2016-0094/
# https://sourceforge.net/p/p7zip/discussion/383043/thread/9d0fb86b/#1dba
#
patch -Np1 < $CWD/CVE-2015-1038.patch
patch -Np1 < $CWD/CVE-2016-2335.patch
make all3 \
OPTFLAGS="$SLKCFLAGS" \