dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.19k stars 4.72k forks source link

FileStream.SetAccessControl() is useless due to missing rights #108658

Open AcidZealot opened 2 weeks ago

AcidZealot commented 2 weeks ago

Description

Under Windows FileStream.SetAccessControl() always fails with ACCESS_DENIED due to missing WRITE_DACL rights for the file handle. There are no such flags in FileAccess enum - so, runtime can't pass WRITE_DACL to CreateFile().

Reproduction Steps

            FileStreamOptions options = new FileStreamOptions() { Access = FileAccess.ReadWrite, Mode = FileMode.OpenOrCreate, Options = FileOptions.None, Share = FileShare.ReadWrite | FileShare.Delete };
            FileStream fileStream = new FileStream("D:\\testfile", options);
            FileSecurity fileSecurity = new FileSecurity();
            FileSystemAccessRule fileRule = new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, domainSid: null), FileSystemRights.FullControl, AccessControlType.Allow);
            fileSecurity.SetAccessRule(fileRule);
            fileStream.SetAccessControl(fileSecurity);

Expected behavior

File security is updated: added rights for all users

Actual behavior

Unhandled exception. System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.
   at System.Security.AccessControl.Win32.SetSecurityInfo(ResourceType type, String name, SafeHandle handle, SecurityInfos securityInformation, SecurityIdentifier owner, SecurityIdentifier group, GenericAcl sacl, GenericAcl dacl)
   at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
   at System.Security.AccessControl.NativeObjectSecurity.Persist(SafeHandle handle, AccessControlSections includeSections)
   at System.Security.AccessControl.FileSystemSecurity.Persist(SafeFileHandle handle, String _)
   at FileSecTest.Program.Main(String[] args)

Regression?

No response

Known Workarounds

1) use FileSystemAclExtensions.SetAccessControl() method 2) Open file with other methods (interop?) and pass SafeFileHandle with WRITE_DACL rights to FileStream constructor.

Configuration

.net 8.0

Other information

No response

dotnet-policy-service[bot] commented 2 weeks ago

Tagging subscribers to this area: @dotnet/area-system-io See info in area-owners.md if you want to be subscribed.

KalleOlaviNiemitalo commented 2 weeks ago

2. Open file with other methods (interop?) and pass SafeFileHandle with WRITE_DACL rights to FileStream constructor.

FileSystemAclExtensions also has public static FileStream Create(FileInfo, FileMode, FileSystemRights, FileShare, int, FileOptions, FileSecurity?), to which you can pass FileSystemRights.ChangePermissions.

(A bit surprising that FileStreamOptions supports UnixCreateMode but not Windows ACLs.)