Eryk Sun <eryk...@gmail.com> added the comment:

> you should go through your current user's apps directory 
> (C:\Users\name\AppData\Local\Microsoft\WindowsApps\<package family>,
> which contains only symlinks to the actual executables).

"%LocalAppData%\Microsoft\WindowsApps" contains IO_REPARSE_TAG_APPEXECLINK 
reparse points. An application-execution link is not like a regular symlink, 
i.e. it does not have the name-surrogate bit set in the tag value. In addition 
to the real application path, an app-exec link also contains the package 
information that the system uses to create the special access token that's 
required in order to execute the application.

I stepped through CreateProcessW in 10.0.18362.175 (slow ring), which has the 
old behavior. The first NtCreateUserProcess system call (the call that actually 
creates the Process object) fails with STATUS_IO_REPARSE_TAG_NOT_HANDLED. 
CreateProcessW handles this by getting the package information from the reparse 
point and creating a new token that contains 3 additional security attributes 
(WIN://SYSAPPID, WIN://PKG, and WIN://PKGHOSTID). For the subsequent 
NtCreateUserProcess system call, it uses the real path under 
"%ProgramFiles%\WindowsApps" and impersonates the new access token. 

The real executable has two ACEs for standard users. There's a basic 
access-allowed ACE that grants read access, but does not grant execute access. 
There's also an access-allowed callback ACE that grants read and execute 
access. Normally the kernel security routines ignore callback ACEs in an access 
check, since they're intended for an application-defined callback in the 
user-mode AuthZ API. Apparently something is special-casing the access check in 
this case, to conditionally check the security attributes in the token in order 
to apply this callback ACE. If I remove the callback ACE, users can no longer 
execute python.exe, so I know this is the ACE that's granting execute access.

Back to CreateProcessW. If I try to directly execute the real executable in 
"%ProgramFiles%\WindowsApps", the NtCreateUserProcess system call fails with 
STATUS_ACCESS_DENIED, as expected. But then CreateProcessW does something that 
I didn't expect. It parses out the base filename "python.exe" and joins it to 
"%LocalAppData%\Microsoft\WindowsApps". If it finds the app-exec link, then it 
reads it to create the special package access token, as if we had run the 
app-exec link directly. If I had to guess, I would assume this behavior has 
been disabled in newer versions of Windows 10. I'm using the slow ring for now, 
so I don't have a way to test this guess.

----------
nosy: +eryksun

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue37369>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to