-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
File.OpenHandle #53344
File.OpenHandle #53344
Conversation
…Helpers to SafeFileHandle itself
…le.OpenHandle to FileStreamHelpers
Tagging subscribers to this area: @carlossanlop Issue DetailsContributes to #24847
|
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
Outdated
Show resolved
Hide resolved
{ | ||
IntPtr fileHandle = NtCreateFile(fullPath, mode, access, share, options, preallocationSize); | ||
|
||
return ValidateFileHandle(new SafeFileHandle(fileHandle, ownsHandle: true), fullPath, (options & FileOptions.Asynchronous) != 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a bunch of other options being set below, e.g. disabling Inheritable, setting SECURITY_SQOS_PRESENT and SECURITY_ANONYMOUS, etc... why is that not relevant if a preallocation size is set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's set, but in a different place:
runtime/src/libraries/Common/src/Interop/Windows/NtDll/Interop.NtCreateFile.cs
Lines 81 to 87 in d5cef92
// For mitigating local elevation of privilege attack through named pipes | |
// make sure we always call NtCreateFile with SECURITY_ANONYMOUS so that the | |
// named pipe server can't impersonate a high privileged client security context | |
SECURITY_QUALITY_OF_SERVICE securityQualityOfService = new SECURITY_QUALITY_OF_SERVICE( | |
ImpersonationLevel.Anonymous, // SECURITY_ANONYMOUS | |
ContextTrackingMode.Static, | |
effectiveOnly: false); |
I decided to follow @JeremyKuhne suggestion and stop using CreateFileW
and NtCreateFile
and use NtCreateFile
only. There is a minor perf gain (2% on opening the file) but the code became much cleaner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How are we handling https://docs.microsoft.com/en-us/windows/win32/devnotes/calling-internal-apis ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stephentoub for some reason NtCreateFile()
has two docs:
- https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile (says that it's internal)
- https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntcreatefile (no mention of internal)
I am not sure which doc is right, but we have been using NtCreateFile
for more than 3 years now: dotnet/corefx#27195
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does NtCreateFile support every kind of file the higher level CreateFileW does? My understanding is NtCreateFile is a bit faster because CreateFile does additional work to special-case various things.
src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs
Outdated
Show resolved
Hide resolved
…omFile.ReadAtOffset are going to need it)
@stephentoub apologies for the confusion, it's not ready for review yet. I've converted it to a draft. |
…s it's a Windows-specific concept
…Seek for regular files
Co-authored-by: Stephen Toub <stoub@microsoft.com>
{ | ||
result |= DesiredAccess.DELETE; // required by FILE_DELETE_ON_CLOSE and FILE_SUPERSEDE (which deletes a file if it exists) | ||
result |= DesiredAccess.DELETE; // required by FILE_DELETE_ON_CLOSE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was a bug, I've added a test CreateAndOverwrite
that ensures that everything works as expected
@@ -78,18 +74,28 @@ private static void ValidateHandle(SafeFileHandle handle, FileAccess access, int | |||
{ | |||
throw new ArgumentOutOfRangeException(nameof(access), SR.ArgumentOutOfRange_Enum); | |||
} | |||
else if (bufferSize <= 0) | |||
else if (bufferSize < 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is something that I've missed in #52928
* with NtCreateFile there is no need for Validation (NtCreateFile returns error and we never create a safe file handle) * unify status codes * complete error mapping
Closing in favor of #53669 |
I've moved all the logic responsible for opening and initializing
SafeFileHandle
toSafeFileHandle
. A lot of duplicated code (mostly for initializingThreadPoolBinding
) got removed. On Unix, it's also now much more clear how many syscalls we perform to just open a file.Other changes:
NtCreateFile
for cases whenpreallocationSize
was specified andCreateFileW
when not, I've followed @JeremyKuhne suggestion and switched to usingNtCreateFile
only. This has simplified the code and provided some minor perf gain. I've discovered a bug in the previous implementation (related toDesiredAccess.DELETE
) fixed it, and added a testfstat()
to ensure that a given file is not a directory we can also determine whether given file is seekable or not. This has removed one syscall for the initialization ofCanSeek
.Contributes to #24847