This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients eryksun, paul.moore, saschanaz, steve.dower, tim.golden, zach.ware
Date 2020-06-20.21:02:30
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1592686951.14.0.329462976999.issue41053@roundup.psfhosted.org>
In-reply-to
Content
By design, appexec links (i.e. app execution aliases) cannot be followed automatically. There is no handler for them in the kernel. WinAPI CreateFileW fails with ERROR_CANT_ACCESS_FILE (1920), and the underlying NT status value is STATUS_IO_REPARSE_TAG_NOT_HANDLED (0xC0000279). 

Since 3.8, os.stat handles ERROR_CANT_ACCESS_FILE in all cases by trying to return the result for the reparse point instead. This at least allows getting the st_file_attributes and st_reparse_tag values. For example:

    >>> s = os.stat(sys.executable)
    >>> s.st_file_attributes & stat.FILE_ATTRIBUTE_REPARSE_POINT
    1024
    >>> s.st_reparse_tag == stat.IO_REPARSE_TAG_APPEXECLINK
    True 

CreateProcessW follows app-exec links manually by reading the reparse point. But it's not that simple. The link target under "%ProgramFiles%\WindowsApps" isn't unconditionally executable by standard users. In other words, unless a particular condition is met, trying to execute the target file fails with access denied. Execute access depends on a conditional access-control entry (conditional ACEs are supported in the kernel since Windows 8) that grants access if the user's access token contains a "WIN://SYSAPPID" attribute that identifies the package. Here's the SDDL definition of this ACE for the app distribution of Python 3.9:

    (XA;ID;0x1200a9;;;BU;(WIN://SYSAPPID Contains "PYTHONSOFTWAREFOUNDATION.PYTHON.3.9_QBZ5N2KFRA8P0")

        "XA" is an access-allowed callback (conditional) ACE
        "ID" means the ACE is inherited from the parent directory
        "BU" is the security principal BUILTIN\Users (local group)
        Access Mask 0x1200a9:
            FILE_GENERIC_READ | FILE_GENERIC_EXECUTE:
                SYNCHRONIZE
                READ_CONTROL
                FILE_READ_ATTRIBUTES
                FILE_EXECUTE
                FILE_READ_EA
                FILE_READ_DATA

If the app is installed for the user, CreateProcessW handles the access denied result by creating and impersonating a custom access token to execute the app, which includes the required WIN://SYSAPPID security attribute. You can attach a debugger to see the security attributes added to the app token:

    0:003> !token

    [...]

    Security Attributes Information:
     00 Attribute Name: WIN://SYSAPPID
        Value Type  : TOKEN_SECURITY_ATTRIBUTE_TYPE_STRING
        Value[0]    : PythonSoftwareFoundation.Python.3.9_3.9.179.0_x64__qbz5n2kfra8p0
        Value[1]    : Python
        Value[2]    : PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0

    [...]
History
Date User Action Args
2020-06-20 21:02:31eryksunsetrecipients: + eryksun, paul.moore, tim.golden, zach.ware, steve.dower, saschanaz
2020-06-20 21:02:31eryksunsetmessageid: <1592686951.14.0.329462976999.issue41053@roundup.psfhosted.org>
2020-06-20 21:02:31eryksunlinkissue41053 messages
2020-06-20 21:02:30eryksuncreate