diff options
author | Justin Lecher <jlec@gentoo.org> | 2015-06-22 07:12:51 +0000 |
---|---|---|
committer | Justin Lecher <jlec@gentoo.org> | 2015-06-22 07:12:51 +0000 |
commit | 6e92939746748be00fc6a5414499da466107cd9c (patch) | |
tree | ac1edfefaf4ec8618e0c77062d4f7b63a1429c0d /app-arch | |
parent | Add proper perl dep, bug #552790. Fix gtk-doc install path. (diff) | |
download | gentoo-2-6e92939746748be00fc6a5414499da466107cd9c.tar.gz gentoo-2-6e92939746748be00fc6a5414499da466107cd9c.tar.bz2 gentoo-2-6e92939746748be00fc6a5414499da466107cd9c.zip |
Fix CVE-2015-1038 in latest version, bug #536012
(Portage version: 2.2.20/cvs/Linux x86_64, signed Manifest commit with key E9402A79B03529A2!)
Diffstat (limited to 'app-arch')
-rw-r--r-- | app-arch/p7zip/ChangeLog | 9 | ||||
-rw-r--r-- | app-arch/p7zip/files/p7zip-9.38.1-CVE-2015-1038.patch | 283 | ||||
-rw-r--r-- | app-arch/p7zip/p7zip-9.38.1-r2.ebuild (renamed from app-arch/p7zip/p7zip-9.38.1-r1.ebuild) | 6 |
3 files changed, 295 insertions, 3 deletions
diff --git a/app-arch/p7zip/ChangeLog b/app-arch/p7zip/ChangeLog index d82fb59c897d..261d544cbe50 100644 --- a/app-arch/p7zip/ChangeLog +++ b/app-arch/p7zip/ChangeLog @@ -1,6 +1,13 @@ # ChangeLog for app-arch/p7zip # Copyright 1999-2015 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/app-arch/p7zip/ChangeLog,v 1.175 2015/06/21 18:21:30 zlogene Exp $ +# $Header: /var/cvsroot/gentoo-x86/app-arch/p7zip/ChangeLog,v 1.176 2015/06/22 07:12:51 jlec Exp $ + +*p7zip-9.38.1-r2 (22 Jun 2015) + + 22 Jun 2015; Justin Lecher <jlec@gentoo.org> + +files/p7zip-9.38.1-CVE-2015-1038.patch, +p7zip-9.38.1-r2.ebuild, + -p7zip-9.38.1-r1.ebuild: + Fix CVE-2015-1038 in latest version, bug #536012 21 Jun 2015; Mikle Kolyada <zlogene@gentoo.org> p7zip-9.20.1-r5.ebuild: alpha stable wrt bug #536012 diff --git a/app-arch/p7zip/files/p7zip-9.38.1-CVE-2015-1038.patch b/app-arch/p7zip/files/p7zip-9.38.1-CVE-2015-1038.patch new file mode 100644 index 000000000000..c4e443679b05 --- /dev/null +++ b/app-arch/p7zip/files/p7zip-9.38.1-CVE-2015-1038.patch @@ -0,0 +1,283 @@ +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: http://sourceforge.net/p/p7zip/bugs/147/ +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 +@@ -1215,7 +1215,7 @@ STDMETHODIMP CAgentFolder::Extract(const + HRESULT result = _agentSpec->GetArchive()->Extract(&realIndices.Front(), + realIndices.Size(), testMode, extractCallback); + if (result == S_OK) +- result = extractCallbackSpec->SetDirsTimes(); ++ result = extractCallbackSpec->SetFinalAttribs(); + return result; + COM_TRY_END + } +--- a/CPP/7zip/UI/Client7z/Client7z.cpp ++++ b/CPP/7zip/UI/Client7z/Client7z.cpp +@@ -222,8 +222,11 @@ private: + COutFileStream *_outFileStreamSpec; + CMyComPtr<ISequentialOutStream> _outFileStream; + ++ CObjectVector<NWindows::NFile::NDir::CDelayedSymLink> _delayedSymLinks; ++ + public: + void Init(IInArchive *archiveHandler, const FString &directoryPath); ++ HRESULT SetFinalAttribs(); + + UInt64 NumErrors; + bool PasswordIsDefined; +@@ -441,11 +444,23 @@ STDMETHODIMP CArchiveExtractCallback::Se + } + _outFileStream.Release(); + if (_extractMode && _processedFileInfo.AttribDefined) +- SetFileAttrib(_diskFilePath, _processedFileInfo.Attrib); ++ SetFileAttrib(_diskFilePath, _processedFileInfo.Attrib, &_delayedSymLinks); + PrintNewLine(); + return S_OK; + } + ++HRESULT CArchiveExtractCallback::SetFinalAttribs() ++{ ++ HRESULT result = S_OK; ++ ++ for (int i = 0; i != _delayedSymLinks.Size(); ++i) ++ if (!_delayedSymLinks[i].Create()) ++ result = E_FAIL; ++ ++ _delayedSymLinks.Clear(); ++ ++ return result; ++} + + STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) + { +@@ -912,6 +927,8 @@ int MY_CDECL main(int numArgs, const cha + // extractCallbackSpec->PasswordIsDefined = true; + // extractCallbackSpec->Password = L"1"; + HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback); ++ if (result == S_OK) ++ result = extractCallbackSpec->SetFinalAttribs(); + if (result != S_OK) + { + PrintError("Extract Error"); +--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp ++++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp +@@ -1083,7 +1083,7 @@ STDMETHODIMP CArchiveExtractCallback::Se + NumFiles++; + + if (_extractMode && _fi.AttribDefined) +- SetFileAttrib(_diskFilePath, _fi.Attrib); ++ SetFileAttrib(_diskFilePath, _fi.Attrib, &_delayedSymLinks); + RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted)); + return S_OK; + COM_TRY_END +@@ -1149,8 +1149,9 @@ static int GetNumSlashes(const FChar *s) + } + } + +-HRESULT CArchiveExtractCallback::SetDirsTimes() ++HRESULT CArchiveExtractCallback::SetFinalAttribs() + { ++ HRESULT result = S_OK; + CRecordVector<CExtrRefSortPair> pairs; + pairs.ClearAndSetSize(_extractedFolderPaths.Size()); + unsigned i; +@@ -1187,5 +1188,12 @@ HRESULT CArchiveExtractCallback::SetDirs + (WriteATime && ATimeDefined) ? &ATime : NULL, + (WriteMTime && MTimeDefined) ? &MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL)); + } +- return S_OK; ++ ++ for (int i = 0; i != _delayedSymLinks.Size(); ++i) ++ if (!_delayedSymLinks[i].Create()) ++ result = E_FAIL; ++ ++ _delayedSymLinks.Clear(); ++ ++ return result; + } +--- 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" +@@ -213,6 +215,8 @@ class CArchiveExtractCallback: + bool _saclEnabled; + #endif + ++ CObjectVector<NWindows::NFile::NDir::CDelayedSymLink> _delayedSymLinks; ++ + void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath); + HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined); + HRESULT GetUnpackSize(); +@@ -293,7 +297,7 @@ public: + _baseParentFolder = indexInArc; + } + +- HRESULT SetDirsTimes(); ++ HRESULT SetFinalAttribs(); + }; + + #endif +--- a/CPP/7zip/UI/Common/Extract.cpp ++++ b/CPP/7zip/UI/Common/Extract.cpp +@@ -170,7 +170,7 @@ static HRESULT DecompressArchive( + else + result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, ecs); + if (result == S_OK && !options.StdInMode) +- result = ecs->SetDirsTimes(); ++ result = ecs->SetFinalAttribs(); + return callback->ExtractResult(result); + } + +--- a/CPP/Windows/FileDir.cpp ++++ b/CPP/Windows/FileDir.cpp +@@ -343,7 +343,8 @@ static int convert_to_symlink(const char + return -1; + } + +-bool SetFileAttrib(CFSTR fileName, DWORD fileAttributes) ++bool SetFileAttrib(CFSTR fileName, DWORD fileAttributes, ++ CObjectVector<CDelayedSymLink> *delayedSymLinks) + { + if (!fileName) { + SetLastError(ERROR_PATH_NOT_FOUND); +@@ -375,7 +376,9 @@ bool SetFileAttrib(CFSTR fileName, DWORD + 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("SetFileAttrib(%s,%d) : false-3\n",(const char *)name,fileAttributes))) + return false; + } +@@ -885,6 +888,43 @@ bool CTempDir::Remove() + return !_mustBeDeleted; + } + ++#ifdef ENV_UNIX ++ ++CDelayedSymLink::CDelayedSymLink(const char * 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_FILE_DIR_H + + #include "../Common/MyString.h" ++#include "../Common/MyVector.h" + + #include "FileIO.h" + +@@ -11,11 +12,14 @@ namespace NWindows { + namespace NFile { + namespace NDir { + ++class CDelayedSymLink; ++ + bool GetWindowsDir(FString &path); + bool GetSystemDir(FString &path); + + bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime); +-bool SetFileAttrib(CFSTR path, DWORD attrib); ++bool SetFileAttrib(CFSTR path, DWORD attrib, ++ CObjectVector<CDelayedSymLink> *delayedSymLinks = 0); + bool MyMoveFile(CFSTR existFileName, CFSTR newFileName); + + #ifndef UNDER_CE +@@ -69,6 +73,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(const char * source); ++ bool Create(); ++#else // !ENV_UNIX ++public: ++ CDelayedSymLink(const char * source) {} ++ bool Create() { return true; } ++#endif // ENV_UNIX ++}; ++ + #if !defined(UNDER_CE) + class CCurrentDirRestorer + { diff --git a/app-arch/p7zip/p7zip-9.38.1-r1.ebuild b/app-arch/p7zip/p7zip-9.38.1-r2.ebuild index baf02da63dd2..867de5165649 100644 --- a/app-arch/p7zip/p7zip-9.38.1-r1.ebuild +++ b/app-arch/p7zip/p7zip-9.38.1-r2.ebuild @@ -1,6 +1,6 @@ # Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/app-arch/p7zip/p7zip-9.38.1-r1.ebuild,v 1.1 2015/05/04 12:23:31 jlec Exp $ +# $Header: /var/cvsroot/gentoo-x86/app-arch/p7zip/p7zip-9.38.1-r2.ebuild,v 1.1 2015/06/22 07:12:51 jlec Exp $ EAPI=5 @@ -30,7 +30,9 @@ DEPEND="${RDEPEND} S=${WORKDIR}/${PN}_${PV} src_prepare() { - epatch "${FILESDIR}"/${P}-osversion.patch + epatch \ + "${FILESDIR}"/${P}-osversion.patch \ + "${FILESDIR}"/${P}-CVE-2015-1038.patch if ! use pch; then sed "s:PRE_COMPILED_HEADER=StdAfx.h.gch:PRE_COMPILED_HEADER=:g" -i makefile.* || die |