Cygwin: fix up cached DOS file attributes after file creation

The file attributes after creating a file are not necessarily
identical to the attributes we passed as argument to NtCreateFile.
This results in subsequent operations like fchmod or facl to
set the DOS file attributes to unexpected values.

The fix is to request file attributes from the OS after file creation
and cache those.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2021-11-16 19:44:21 +01:00
parent 9980177def
commit 41de4b6fd7
2 changed files with 33 additions and 21 deletions

View File

@ -676,8 +676,6 @@ fhandler_base::open (int flags, mode_t mode)
/* If mode has no write bits set, and ACLs are not used, we set /* If mode has no write bits set, and ACLs are not used, we set
the DOS R/O attribute. */ the DOS R/O attribute. */
file_attributes |= FILE_ATTRIBUTE_READONLY; file_attributes |= FILE_ATTRIBUTE_READONLY;
/* The file attributes are needed for later use in, e.g. fchmod. */
pc.file_attributes (file_attributes);
/* Never set the WRITE_DAC flag here. Calls to fstat may return /* Never set the WRITE_DAC flag here. Calls to fstat may return
wrong st_ctime information after calls to fchmod, fchown, etc wrong st_ctime information after calls to fchmod, fchown, etc
because Windows only guarantees the update of metadata when because Windows only guarantees the update of metadata when
@ -720,28 +718,38 @@ fhandler_base::open (int flags, mode_t mode)
goto done; goto done;
} }
/* Always create files using a NULL SD. Create correct permission bits if (io.Information == FILE_CREATED)
afterwards, maintaining the owner and group information just like chmod. {
/* Correct file attributes are needed for later use in, e.g. fchmod. */
FILE_BASIC_INFORMATION fbi;
This is done for two reasons. if (!NT_SUCCESS (NtQueryInformationFile (fh, &io, &fbi, sizeof fbi,
FileBasicInformation)))
fbi.FileAttributes = file_attributes | FILE_ATTRIBUTE_ARCHIVE;
pc.file_attributes (fbi.FileAttributes);
On Windows filesystems we need to create the file with default /* Always create files using a NULL SD. Create correct permission bits
permissions to allow inheriting ACEs. When providing an explicit DACL afterwards, maintaining the owner and group information just like
in calls to [Nt]CreateFile, the created file will not inherit default chmod. This is done for two reasons.
permissions from the parent object. This breaks not only Windows
inheritance, but also POSIX ACL inheritance.
Another reason to do this are remote shares. Files on a remote share On Windows filesystems we need to create the file with default
are created as the user used for authentication. In a domain that's permissions to allow inheriting ACEs. When providing an explicit DACL
usually the user you're logged in as. Outside of a domain you're in calls to [Nt]CreateFile, the created file will not inherit default
authenticating using a local user account on the sharing machine. permissions from the parent object. This breaks not only Windows
If the SIDs of the client machine are used, that's entirely inheritance, but also POSIX ACL inheritance.
unexpected behaviour. Doing it like we do here creates the expected SD
in a domain as well as on standalone servers. Another reason to do this are remote shares. Files on a remote share
This is the result of a discussion on the samba-technical list, starting at are created as the user used for authentication. In a domain that's
http://lists.samba.org/archive/samba-technical/2008-July/060247.html */ usually the user you're logged in as. Outside of a domain you're
if (io.Information == FILE_CREATED && has_acls ()) authenticating using a local user account on the sharing machine.
set_created_file_access (fh, pc, mode); If the SIDs of the client machine are used, that's entirely unexpected
behaviour. Doing it like we do here creates the expected SD in a
domain as well as on standalone servers. This is the result of a
discussion on the samba-technical list, starting at
http://lists.samba.org/archive/samba-technical/2008-July/060247.html */
if (has_acls ())
set_created_file_access (fh, pc, mode);
}
/* If you O_TRUNC a file on Linux, the data is truncated, but the EAs are /* If you O_TRUNC a file on Linux, the data is truncated, but the EAs are
preserved. If you open a file on Windows with FILE_OVERWRITE{_IF} or preserved. If you open a file on Windows with FILE_OVERWRITE{_IF} or

View File

@ -18,3 +18,7 @@ Bug Fixes
running bash in Windows Terminal and inserting an emoji does not running bash in Windows Terminal and inserting an emoji does not
work as expected. work as expected.
Addresses: https://github.com/git-for-windows/git/issues/3281 Addresses: https://github.com/git-for-windows/git/issues/3281
- Fix long-standing problem that fchmod or facl on newly created files
screw up the DOS file attributes.
Addresses: https://cygwin.com/pipermail/cygwin/2021-November/249909.html