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, izbyshev, paul.moore, steve.dower, tim.golden, vstinner, zach.ware
Date 2021-01-22.04:53:10
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1611291191.85.0.551388798793.issue42606@roundup.psfhosted.org>
In-reply-to
Content
FYI, here are the access rights applicable to files, including their membership in generic (R)ead, (W)rite, and e(X)execute access:

    0x0100_0000 --- ACCESS_SYSTEM_SECURITY
    0x0010_0000 RWX SYNCHRONIZE
    0x0008_0000 --- WRITE_OWNER
    0x0004_0000 --- WRITE_DAC
    0x0002_0000 RWX READ_CONTROL
    0x0001_0000 --- DELETE

    0x0000_0001 R-- FILE_READ_DATA
    0x0000_0002 -W- FILE_WRITE_DATA
    0x0000_0004 -W- FILE_APPEND_DATA
    0x0000_0008 R-- FILE_READ_EA
    0x0000_0010 -W- FILE_WRITE_EA
    0x0000_0020 --X FILE_EXECUTE
    0x0000_0040 --- FILE_DELETE_CHILD
    0x0000_0080 R-X FILE_READ_ATTRIBUTES
    0x0000_0100 -W- FILE_WRITE_ATTRIBUTES

> _wopen() uses GENERIC_READ/GENERIC_WRITE access rights, but 
> _wopen() doesn't have a contractual obligation to do exactly 
> that AFAIU. For example, if it got some extra access rights, 
> then my code would "drop" them while switching FILE_WRITE_DATA off.

I overlooked a case that's a complication. For O_TEMPORARY, the open uses FILE_FLAG_DELETE_ON_CLOSE; adds DELETE to the requested access; and adds FILE_SHARE_DELETE to the share mode. 

With delete-on-close, a file gets marked as deleted as soon as the last handle for the kernel File is closed. This is the classic Windows 'deleted' state in which the filename remains linked in the directory but inaccessible for any new access (as opposed to the immediate POSIX style delete that DeleteFileW attempts in Windows 10). Existing opens (i.e. kernel File objects from CreateFileW) are still valid, and, if they have delete access, they can even be used to undelete the file via SetFileInformationByHandle: FileDispositionInfo. 

_Py_wopen_noraise() can easily keep the required DELETE access. The complication is that you have to be careful not to close the original file descriptor until after you've successfully created the duplicate file descriptor. If it fails, you have to return the original file descriptor from _wopen(). If you close all handles for the kernel File and fail the call, the side effect of deleting the file is unacceptable. 

The C runtime itself isn't careful about using O_TEMPORARY in text mode, given how it closes the file if truncation fails or has to open the file twice in O_WRONLY mode in order to read the BOM. But at least it's reliable in binary mode. The file descriptor is pre-allocated with _alloc_osfhnd(), so it won't fail after CreateFileW() is called.

> Are you aware of a common scenario when a regular file allows 
> appending but not writing?

It's certainly not common for regular files. (It's more common for directories, for which append access corresponds to the right to create a subdirectory.) Maybe users are only allowed to append to a given log file. But I think most scenarios will be accidental. 

For example, say an admin wants to deny write access to standard users. Denying simple or generic write access is wrong, since doing so also denies rights required for reading, i.e. synchronize and read-control. So the admin runs the following command to deny only write-data access: `icacls filename /deny *BU:(WD)`. This forgets about append-data (AD) access. It's still sufficient for most applications, which request generic-write access.
History
Date User Action Args
2021-01-22 04:53:11eryksunsetrecipients: + eryksun, paul.moore, vstinner, tim.golden, zach.ware, steve.dower, izbyshev
2021-01-22 04:53:11eryksunsetmessageid: <1611291191.85.0.551388798793.issue42606@roundup.psfhosted.org>
2021-01-22 04:53:11eryksunlinkissue42606 messages
2021-01-22 04:53:10eryksuncreate