[Bug 49334] onefile applications created with PyInstaller 3.6 fail, reporting 'INTERNAL ERROR: cannot create temporary directory' (improper handling of owner rights SID '{S-1-3-4}')
WineHQ Bugzilla
wine-bugs at winehq.org
Tue Jun 9 06:52:46 CDT 2020
https://bugs.winehq.org/show_bug.cgi?id=49334
Anastasius Focht <focht at gmx.net> changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|-unknown |wineserver
Severity|major |normal
Keywords| |download, source
Ever confirmed|0 |1
URL| |https://github.com/pyinstal
| |ler/pyinstaller
CC| |focht at gmx.net
Summary|Binaries compiled with |onefile applications
|PyInstaller on Wine crash |created with PyInstaller
|with error, affects |3.6 fail, reporting
|Anaconda installation, too. |'INTERNAL ERROR: cannot
| |create temporary directory'
| |(improper handling of owner
| |rights SID '{S-1-3-4}')
Status|UNCONFIRMED |NEW
Version|5.0.1 |5.0
--- Comment #1 from Anastasius Focht <focht at gmx.net> ---
Hello folks,
confirming.
The upstream change that caused this breakage is here:
https://github.com/pyinstaller/pyinstaller/commit/42a67148b3bdf9211fda8499fdc5b63acdd7e6cc
(master branch, included in 3.6 release)
--- quote ---
[SECURITY] Bootloader: Fix insecure directory permissions of sys._MEI…
…PATH.
Important: This security fix effects *all Windows software frozen by
PyInstaller* in "onefile" mode.
This fix prevents a Local Privilege Escalation vulnerability that is
present only on Windows and in this particular case:
If a software frozen by PyInstaller in "onefile" mode is launched
by a (privileged) user who has his/her "TempPath" resolving to a world
writable directory. This is the case e.g. if the software is
launched as a service or as a scheduled task using a system account
(in which case TempPath will default to `C:\Windows\Temp`).
All Windows version have been vulnerable, since _wmkdir() does not
enforce restricted permissions. On Posix-systems mkdtemp() is used,
which already enforce permissions, so they have not been affected.
The fix is done by implementing a new pyi_win32_mkdir() that enforces
proper permissions for the created directory.
While PyInstaller itself was not vulnerable, all Windows software frozen
by PyInstaller in "onefile" mode is vulnerable. If you are using
PyInstaller to freeze Windows software using "onefile" mode, you should
upgrade PyInstaller and rebuild your software.
Fixes CVE-2019-16784.
Co-authored-by: Hartmut Goebel <h.goebel at crazy-compilers.com>
--- quote ---
The code:
--- snip ---
/* Create a directory at path with restricted permissions.
* The directory owner will be the only one with permissions on the created
* dir. Calling this function is equivalent to callin chmod(path, 0700) on
* Posix.
* Returns 0 on success, -1 on error.
*/
int
pyi_win32_mkdir(const wchar_t *path)
{
wchar_t stringSecurityDesc[] = // ACE String :
L"D:" // DACL (D) :
L"(A;" // Authorize (A)
L";FA;" // FILE_ALL_ACCESS (FA)
L";;S-1-3-4)"; // For the current directory owner (SID: S-1-3-4)
// no other permissions are granted
SECURITY_ATTRIBUTES securityAttr;
PSECURITY_DESCRIPTOR *lpSecurityDesc;
securityAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
securityAttr.bInheritHandle = FALSE;
lpSecurityDesc = &securityAttr.lpSecurityDescriptor;
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(
stringSecurityDesc,
SDDL_REVISION_1,
lpSecurityDesc,
NULL)) {
return -1;
}
if (!CreateDirectoryW(path, &securityAttr)) {
return -1;
};
return 0;
}
--- snip ---
Recipe for reproduction:
https://github.com/pyinstaller/pyinstaller/issues/4628#issuecomment-586806948
--- snip ---
$ wget https://www.python.org/ftp/python/3.8.1/python-3.8.1-amd64.exe
$ wine ./python-3.8.1-amd64.exe /passive
$ wine py -m pip install --upgrade pip
$ wine py -m pip install pyinstaller
$ wget https://github.com/pinobatch/lorom-template/raw/master/tools/wav2brr.py
$ wine \path\to\pyinstaller.exe --onefile -d bootloader wav2brr.py
--- snip ---
Relevant part of trace log running the onefile app:
--- snip ---
$ WINEDEBUG=+seh,+relay,+server,+advapi,+security wine ./wav2brr.exe >>log.txt
2>&1
...
00c0:Call
advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW(002198b8
L"D:(A;;FA;;;S-1-3-4)",00000001,002198a8,00000000) ret=140005964
00c0:Call sechost.ConvertStringSecurityDescriptorToSecurityDescriptorW(002198b8
L"D:(A;;FA;;;S-1-3-4)",00000001,002198a8,00000000) ret=7bca06ef
...
00c0:trace:security:parse_acl L"(A;;FA;;;S-1-3-4)"
...
00c0:Ret sechost.ConvertStringSecurityDescriptorToSecurityDescriptorW()
retval=00000001 ret=7bca06ef
00c0:Ret advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW()
retval=00000001 ret=140005964
00c0:Call KERNEL32.CreateDirectoryW(0011f710
L"C:\\users\\focht\\Temp\\_MEI1882",002198a0) ret=14000598c
00c0:Call kernelbase.CreateDirectoryW(0011f710
L"C:\\users\\focht\\Temp\\_MEI1882",002198a0) ret=7bca06ef
00c0:Call ntdll.RtlDosPathNameToNtPathName_U(0011f710
L"C:\\users\\focht\\Temp\\_MEI1882",00219728,00000000,00000000) ret=7b01447e
00c0:Ret ntdll.RtlDosPathNameToNtPathName_U() retval=00000001 ret=7b01447e
00c0:Call
ntdll.NtCreateFile(00219720,80100000,00219738,00219768,00000000,00000080,00000001,00000002,00000021,00000000,00000000)
ret=7b014536
00c0: create_file( access=80100000, sharing=00000001, create=2,
options=00000021, attrs=00000080,
objattr={rootdir=0000,attributes=00000040,sd={control=00000004,owner=<not
present>,group=<not
present>,sacl={},dacl={{AceType=ACCESS_ALLOWED_ACE_TYPE,Mask=1f01ff,AceFlags=0,Sid={S-1-3-4}}}},name=L""},
filename="/home/focht/.wine/dosdevices/c:/users/focht/Temp/_MEI1882" )
00c0: create_file() = ACCESS_DENIED { handle=0000 }
00c0:Ret ntdll.NtCreateFile() retval=c0000022 ret=7b014536
...
00c0:Call ntdll.RtlNtStatusToDosError(c0000022) ret=7b01454f
00c0:Ret ntdll.RtlNtStatusToDosError() retval=00000005 ret=7b01454f
00c0:Ret kernelbase.CreateDirectoryW() retval=00000000 ret=7bca06ef
00c0:Ret KERNEL32.CreateDirectoryW() retval=00000000 ret=14000598c
--- snip ---
No SD owner is present so the owner derived from the process token. This
obviously can't work together with specified owner rights SID '{S-1-3-4}'.
sid = '{S-1-3-4}' (from SD)
user = '{S-1-5-21-0-0-0-1000}' (derived from process token)
owner = '{S-1-5-21-0-0-0-1000}' (derived from process token)
https://source.winehq.org/git/wine.git/blob/HEAD:/server/file.c#l533
--- snip ---
...
533 case ACCESS_ALLOWED_ACE_TYPE:
534 aa_ace = (const ACCESS_ALLOWED_ACE *)ace;
535 sid = (const SID *)&aa_ace->SidStart;
536 mode = file_access_to_mode( aa_ace->Mask );
537 if (security_equal_sid( sid, security_world_sid ))
538 {
539 mode = (mode << 6) | (mode << 3) | mode; /* all
*/
540 new_mode |= mode & bits_to_set;
541 bits_to_set &= ~mode;
542 }
543 else if ((security_equal_sid( user, owner ) &&
544 token_sid_present( current->process->token,
sid, FALSE )))
545 {
546 mode = (mode << 6) | (mode << 3); /* user + group
*/
547 new_mode |= mode & bits_to_set;
548 bits_to_set &= ~mode;
549 }
550 else if (security_equal_sid( sid, owner ))
551 {
552 mode = (mode << 6); /* user only */
553 new_mode |= mode & bits_to_set;
554 bits_to_set &= ~mode;
555 }
556 break;
...
--- snip ---
---
I've changed the reported version field back to Wine 5.0 because that's the
earliest version the people reported the problem with. See referenced links to
Github PRs.
$ wine --version
wine-5.10-39-g1752958240
Regards
--
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.
More information about the wine-bugs
mailing list