On Sun, Jan 24, 2016 at 05:11:34PM -0500, Josh Grosse wrote:
> Additional pledge() calls added for Self-Extracting archives. These 
> use a separate executable, which has now been pledged.
> 
> Mitigation for CVE-2015-1038, which upstream has not implemented.
> This is Debian's proposed solution.  
> 
> Debug tokens added to pledge() patches.  Today, brynet@ proposed 
> several secondary pledges to reduce the pledge to stdio rpath,
> and in some cases possibly stdio alone.  These are still in 
> development.  
 
Testing is complete on the reduced pledges.

The test, hash, list, and extract to stdout (x -so) functions are 
pledged "stdio rpath", while the info and benchmark functions are
now pledged "stdio" only.

These were devised by brynet@, and I'm very grateful for the time
Bryan devoted to analyzing the appropriate pledge points.

Revised patches below.

   -Josh-


Index: Makefile
===================================================================
RCS file: /systems/cvs/ports/archivers/p7zip/Makefile,v
retrieving revision 1.28
diff -u -p -r1.28 Makefile
--- Makefile    22 Jan 2016 13:39:08 -0000      1.28
+++ Makefile    25 Jan 2016 00:45:03 -0000
@@ -6,7 +6,7 @@ COMMENT-main=   file archiver with high co
 COMMENT-rar=   rar modules for p7zip
 
 V=             15.09
-REVISION=      1
+REVISION=      2
 DISTNAME=      p7zip_${V}_src_all
 PKGNAME=       p7zip-${V}
 PKGNAME-main=  p7zip-${V}
Index: patches/patch-CPP_7zip_Bundles_SFXCon_SfxCon_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_Bundles_SFXCon_SfxCon_cpp
diff -N patches/patch-CPP_7zip_Bundles_SFXCon_SfxCon_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Bundles_SFXCon_SfxCon_cpp    24 Jan 2016 21:02:56 
-0000
@@ -0,0 +1,48 @@
+$OpenBSD$
+
+Pledge self-extracting archives
+
+--- CPP/7zip/Bundles/SFXCon/SfxCon.cpp.orig    Sat Sep  5 16:22:56 2015
++++ CPP/7zip/Bundles/SFXCon/SfxCon.cpp Sun Jan 24 15:59:24 2016
+@@ -250,6 +250,21 @@ int Main2(
+   #endif
+ )
+ {
++
++#ifndef EXTERNAL_CODECS
++
++#ifdef PLEDGE_DEBUG
++  printf("pledge: 7za 7zr SFX\n");
++#endif //PLEDGE_DEBUG
++
++  if (pledge("stdio rpath wpath cpath fattr", NULL) == -1) {
++    perror("pledge");
++    exit(2);
++  }
++
++#endif
++
++
+   #if defined(_WIN32) && !defined(UNDER_CE)
+   SetFileApisToOEM();
+   #endif
+@@ -371,6 +386,19 @@ int Main2(
+     HRESULT result = codecs->Load();
+     if (result != S_OK)
+       throw CSystemException(result);
++
++#ifdef EXTERNAL_CODECS
++
++#ifdef PLEDGE_DEBUG
++  printf("pledge: 7z SFX\n");
++#endif //PLEDGE_DEBUG
++
++  if (pledge("stdio rpath wpath cpath fattr", NULL) == -1) {
++    perror("pledge");
++    exit(2);
++  }
++
++#endif
+ 
+     if (command.CommandType != NCommandType::kList)
+     {
Index: patches/patch-CPP_7zip_UI_Agent_Agent_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_UI_Agent_Agent_cpp
diff -N patches/patch-CPP_7zip_UI_Agent_Agent_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_UI_Agent_Agent_cpp   24 Jan 2016 18:24:54 -0000
@@ -0,0 +1,19 @@
+$OpenBSD$
+
+Adapted for p7zip 15.09 by Ismail Donmez:
+http://sourceforge.net/p/p7zip/discussion/383043/thread/53f8df4f/
+
+Author: Ben Hutchings <b...@decadent.org.uk>
+Description: Delay creation of symlinks to prevent arbitrary file writes 
(CVE-2015-1038)
+
+--- CPP/7zip/UI/Agent/Agent.cpp.orig   Thu Sep 17 15:02:35 2015
++++ CPP/7zip/UI/Agent/Agent.cpp        Sun Jan 24 13:20:58 2016
+@@ -1515,7 +1515,7 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indic
+   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
+ }
Index: patches/patch-CPP_7zip_UI_Client7z_Client7z_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_UI_Client7z_Client7z_cpp
diff -N patches/patch-CPP_7zip_UI_Client7z_Client7z_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_UI_Client7z_Client7z_cpp     24 Jan 2016 18:24:47 
-0000
@@ -0,0 +1,57 @@
+$OpenBSD$
+
+Adapted for p7zip 15.09 by Ismail Donmez:
+http://sourceforge.net/p/p7zip/discussion/383043/thread/53f8df4f/
+
+Author: Ben Hutchings <b...@decadent.org.uk>
+Description: Delay creation of symlinks to prevent arbitrary file writes 
(CVE-2015-1038)
+
+--- CPP/7zip/UI/Client7z/Client7z.cpp.orig     Sat Oct 17 10:52:30 2015
++++ CPP/7zip/UI/Client7z/Client7z.cpp  Sun Jan 24 13:20:58 2016
+@@ -230,8 +230,11 @@ class CArchiveExtractCallback: (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;
+@@ -449,12 +452,24 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResu
+   }
+   _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)
+ {
+   if (!PasswordIsDefined)
+@@ -914,6 +929,8 @@ int MY_CDECL main(int numArgs, const char *args[])
+       // 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");
Index: patches/patch-CPP_7zip_UI_Common_ArchiveExtractCallback_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_UI_Common_ArchiveExtractCallback_cpp
diff -N patches/patch-CPP_7zip_UI_Common_ArchiveExtractCallback_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_UI_Common_ArchiveExtractCallback_cpp 24 Jan 2016 
18:24:14 -0000
@@ -0,0 +1,44 @@
+$OpenBSD$
+
+Adapted for p7zip 15.09 by Ismail Donmez:
+http://sourceforge.net/p/p7zip/discussion/383043/thread/53f8df4f/
+
+Author: Ben Hutchings <b...@decadent.org.uk>
+Description: Delay creation of symlinks to prevent arbitrary file writes 
(CVE-2015-1038)
+
+--- CPP/7zip/UI/Common/ArchiveExtractCallback.cpp.orig Sat Oct  3 04:49:15 2015
++++ CPP/7zip/UI/Common/ArchiveExtractCallback.cpp      Sun Jan 24 13:20:58 2016
+@@ -1502,7 +1502,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResu
+     NumFiles++;
+ 
+   if (!_stdOutMode && _extractMode && _fi.AttribDefined)
+-    SetFileAttrib(_diskFilePath, _fi.Attrib);
++    SetFileAttrib(_diskFilePath, _fi.Attrib, &_delayedSymLinks);
+   
+   RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted)));
+   
+@@ -1584,8 +1584,9 @@ static unsigned GetNumSlashes(const FChar *s)
+   }
+ }
+ 
+-HRESULT CArchiveExtractCallback::SetDirsTimes()
++HRESULT CArchiveExtractCallback::SetFinalAttribs()
+ {
++  HRESULT result = S_OK;
+   CRecordVector<CExtrRefSortPair> pairs;
+   pairs.ClearAndSetSize(_extractedFolderPaths.Size());
+   unsigned i;
+@@ -1622,5 +1623,12 @@ HRESULT CArchiveExtractCallback::SetDirsTimes()
+       (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;
+ }
Index: patches/patch-CPP_7zip_UI_Common_ArchiveExtractCallback_h
===================================================================
RCS file: patches/patch-CPP_7zip_UI_Common_ArchiveExtractCallback_h
diff -N patches/patch-CPP_7zip_UI_Common_ArchiveExtractCallback_h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_UI_Common_ArchiveExtractCallback_h   24 Jan 2016 
18:24:26 -0000
@@ -0,0 +1,37 @@
+$OpenBSD$
+
+Adapted for p7zip 15.09 by Ismail Donmez:
+http://sourceforge.net/p/p7zip/discussion/383043/thread/53f8df4f/
+
+Author: Ben Hutchings <b...@decadent.org.uk>
+Description: Delay creation of symlinks to prevent arbitrary file writes 
(CVE-2015-1038)
+
+--- CPP/7zip/UI/Common/ArchiveExtractCallback.h.orig   Sat Oct  3 06:29:09 2015
++++ CPP/7zip/UI/Common/ArchiveExtractCallback.h        Sun Jan 24 13:20:58 2016
+@@ -6,6 +6,8 @@
+ #include "../../../Common/MyCom.h"
+ #include "../../../Common/Wildcard.h"
+ 
++#include "../../../Windows/FileDir.h"
++
+ #include "../../IPassword.h"
+ 
+ #include "../../Common/FileStreams.h"
+@@ -237,6 +239,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();
+@@ -330,7 +334,7 @@ class CArchiveExtractCallback:
+   }
+   #endif
+ 
+-  HRESULT SetDirsTimes();
++  HRESULT SetFinalAttribs();
+ };
+ 
+ bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const 
CReadArcItem &item);
Index: patches/patch-CPP_7zip_UI_Common_Extract_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_UI_Common_Extract_cpp
diff -N patches/patch-CPP_7zip_UI_Common_Extract_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_UI_Common_Extract_cpp        24 Jan 2016 18:24:33 
-0000
@@ -0,0 +1,19 @@
+$OpenBSD$
+
+Adapted for p7zip 15.09 by Ismail Donmez:
+http://sourceforge.net/p/p7zip/discussion/383043/thread/53f8df4f/
+
+Author: Ben Hutchings <b...@decadent.org.uk>
+Description: Delay creation of symlinks to prevent arbitrary file writes 
(CVE-2015-1038)
+
+--- CPP/7zip/UI/Common/Extract.cpp.orig        Mon Sep  7 15:47:32 2015
++++ CPP/7zip/UI/Common/Extract.cpp     Sun Jan 24 13:20:58 2016
+@@ -207,7 +207,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);
+ }
+ 
Index: patches/patch-CPP_7zip_UI_Console_Main_cpp
===================================================================
RCS file: 
/systems/cvs/ports/archivers/p7zip/patches/patch-CPP_7zip_UI_Console_Main_cpp,v
retrieving revision 1.1
diff -u -p -r1.1 patch-CPP_7zip_UI_Console_Main_cpp
--- patches/patch-CPP_7zip_UI_Console_Main_cpp  22 Jan 2016 13:38:37 -0000      
1.1
+++ patches/patch-CPP_7zip_UI_Console_Main_cpp  25 Jan 2016 02:52:34 -0000
@@ -1,21 +1,23 @@
 $OpenBSD: patch-CPP_7zip_UI_Console_Main_cpp,v 1.1 2016/01/22 13:38:37 sthen 
Exp $
 
-Pledge archivers/p7zip binaries
+Pledge archivers/p7zip main executables
 
 --- CPP/7zip/UI/Console/Main.cpp.orig  Sat Oct 17 11:20:22 2015
-+++ CPP/7zip/UI/Console/Main.cpp       Mon Jan 18 10:05:31 2016
-@@ -484,6 +484,18 @@ int Main2(
++++ CPP/7zip/UI/Console/Main.cpp       Sun Jan 24 21:51:01 2016
+@@ -484,6 +484,20 @@ int Main2(
    #endif
  )
  {
 +
-+// pledge 7za and 7zr at this point, they take different paths than 7z.  
-+
 +#ifndef EXTERNAL_CODECS
 +
++#ifdef PLEDGE_DEBUG
++  printf("initial pledge: 7za 7zr\n");
++#endif
++
 +  if (pledge("stdio rpath wpath cpath fattr", NULL) == -1) {
 +    perror("pledge");
-+    exit(1);
++    exit(2);
 +  }
 +
 +#endif
@@ -23,21 +25,118 @@ Pledge archivers/p7zip binaries
    #if defined(_WIN32) && !defined(UNDER_CE)
    SetFileApisToOEM();
    #endif
-@@ -579,6 +591,17 @@ int Main2(
-   codecs->CaseSensitiveChange = options.CaseSensitiveChange;
+@@ -580,6 +594,19 @@ int Main2(
    codecs->CaseSensitive = options.CaseSensitive;
    ThrowException_if_Error(codecs->Load());
-+
-+// pledge 7z here
-+
+ 
 +#ifdef EXTERNAL_CODECS
 +
++#ifdef PLEDGE_DEBUG
++  printf("initial pledge: 7z\n");
++#endif
++
 +  if (pledge("stdio rpath wpath cpath fattr", NULL) == -1) {
 +    perror("pledge");
-+    exit(1);
++    exit(2);
 +  }
 +
 +#endif
- 
++
    bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
  
+   if (codecs->Formats.Size() == 0 &&
+@@ -636,6 +663,16 @@ int Main2(
+ 
+   if (options.Command.CommandType == NCommandType::kInfo)
+   {
++
++#ifdef PLEDGE_DEBUG
++  printf("reduced pledge: info\n");
++#endif
++
++  if (pledge("stdio", NULL) == -1) {
++    perror("pledge");
++    exit(2);
++  }
++
+     CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut);
+     unsigned i;
+ 
+@@ -802,6 +839,16 @@ int Main2(
+   }
+   else if (options.Command.CommandType == NCommandType::kBenchmark)
+   {
++
++#ifdef PLEDGE_DEBUG
++  printf("reduced pledge: benchmark\n");
++#endif
++
++  if (pledge("stdio", NULL) == -1) {
++    perror("pledge");
++    exit(2);
++  }
++
+     CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut);
+     hresultMain = BenchCon(EXTERNAL_CODECS_VARS_L
+         options.Properties, options.NumIterations, (FILE *)so);
+@@ -869,6 +916,17 @@ int Main2(
+     if (hresultMain == S_OK)
+     if (isExtractGroupCommand)
+     {
++
++      if (options.Command.IsTestCommand() || options.StdOutMode) {
++#ifdef PLEDGE_DEBUG
++          printf("reduced pledge: test stdout\n");
++#endif
++          if (pledge("stdio rpath", NULL) == -1) {
++              perror("pledge");
++              exit(2);
++        }
++      }
++
+       CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
+       CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
+ 
+@@ -893,7 +951,7 @@ int Main2(
+       #ifndef _NO_CRYPTO
+       openCallback.PasswordIsDefined = options.PasswordEnabled;
+       openCallback.Password = options.Password;
+-      #endif
++      #endiF
+       */
+ 
+       CExtractOptions eo;
+@@ -1029,6 +1087,16 @@ int Main2(
+     }
+     else
+     {
++
++#ifdef PLEDGE_DEBUG
++  printf("reduced pledge: list\n");
++#endif
++
++  if (pledge("stdio rpath", NULL) == -1) {
++    perror("pledge");
++    exit(2);
++  }
++
+       UInt64 numErrors = 0;
+       UInt64 numWarnings = 0;
+       
+@@ -1139,6 +1207,16 @@ int Main2(
+   }
+   else if (options.Command.CommandType == NCommandType::kHash)
+   {
++
++#ifdef PLEDGE_DEBUG
++  printf("reduced pledge: hash\n");
++#endif
++
++  if (pledge("stdio rpath", NULL) == -1) {
++    perror("pledge");
++    exit(2);
++  }
++
+     const CHashOptions &uo = options.HashOptions;
+ 
+     CHashCallbackConsole callback;
Index: patches/patch-CPP_Windows_FileDir_cpp
===================================================================
RCS file: patches/patch-CPP_Windows_FileDir_cpp
diff -N patches/patch-CPP_Windows_FileDir_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_Windows_FileDir_cpp       24 Jan 2016 18:24:59 -0000
@@ -0,0 +1,75 @@
+$OpenBSD$
+
+Adapted for p7zip 15.09 by Ismail Donmez:
+http://sourceforge.net/p/p7zip/discussion/383043/thread/53f8df4f/
+
+Author: Ben Hutchings <b...@decadent.org.uk>
+Description: Delay creation of symlinks to prevent arbitrary file writes 
(CVE-2015-1038)
+
+--- CPP/Windows/FileDir.cpp.orig       Sat Oct 10 08:37:41 2015
++++ CPP/Windows/FileDir.cpp    Sun Jan 24 13:20:58 2016
+@@ -347,7 +347,8 @@ static int convert_to_symlink(const char * name) {
+   return -1;
+ }
+ 
+-bool SetFileAttrib(CFSTR fileName, DWORD fileAttributes)
++bool SetFileAttrib(CFSTR fileName, DWORD fileAttributes,
++                 CObjectVector<CDelayedSymLink> *delayedSymLinks)
+ {
+   if (!fileName) {
+     SetLastError(ERROR_PATH_NOT_FOUND);
+@@ -379,7 +380,9 @@ bool SetFileAttrib(CFSTR fileName, DWORD fileAttribute
+      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;
+         }
+@@ -813,6 +816,43 @@ bool CTempDir::Remove()
+   _mustBeDeleted = !RemoveDirectoryWithSubItems(_path);
+   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
+ 
+ }}}
+ 
Index: patches/patch-CPP_Windows_FileDir_h
===================================================================
RCS file: patches/patch-CPP_Windows_FileDir_h
diff -N patches/patch-CPP_Windows_FileDir_h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_Windows_FileDir_h 24 Jan 2016 18:25:12 -0000
@@ -0,0 +1,66 @@
+$OpenBSD$
+
+Adapted for p7zip 15.09 by Ismail Donmez:
+http://sourceforge.net/p/p7zip/discussion/383043/thread/53f8df4f/
+
+Author: Ben Hutchings <b...@decadent.org.uk>
+Description: Delay creation of symlinks to prevent arbitrary file writes 
(CVE-2015-1038)
+
+--- CPP/Windows/FileDir.h.orig Fri Jun 19 06:52:06 2015
++++ CPP/Windows/FileDir.h      Sun Jan 24 13:20:58 2016
+@@ -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
+@@ -74,6 +78,31 @@ class CTempDir (public)
+   void DisableDeleting() { _mustBeDeleted = false; }
+   bool Create(CFSTR namePrefix) ;
+   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)

Reply via email to