Skip to content
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

Relax LinkTarget so it always returns null when steps on an error #55668

Merged
merged 1 commit into from
Jul 15, 2021

Conversation

jozkee
Copy link
Member

@jozkee jozkee commented Jul 14, 2021

Motivated by #55664. When I was testing that PR, I noticed that I was getting ACCESS DENIED errors sporadically, here's the callstack:

  Unhandled exception. System.UnauthorizedAccessException: Access to the path 'C:\Users\david\AppData\Local\Temp\tapmbdam.rgw\4d2sb45x.hix_FOO_True' is denied.
     at System.IO.FileSystem.GetImmediateLinkTarget(String linkPath, Boolean isDirectory, Boolean throwOnUnreachable, Boolean returnFullPath) in System.Private.CoreLib.dll:token 0x6005ec9+0x3b
     at System.IO.FileSystem.GetLinkTarget(String linkPath, Boolean isDirectory) in System.Private.CoreLib.dll:token 0x6005ec8+0x0
     at System.IO.FileSystemInfo.get_LinkTarget() in System.Private.CoreLib.dll:token 0x6005ee2+0xf
     at Microsoft.Extensions.FileProviders.Physical.FileSystemInfoHelper.ResolveFileLinkTarget(FileInfo fileInfo) in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\Internal\FileSystemInfoHelper.cs:line 44
     at Microsoft.Extensions.FileProviders.Physical.FileSystemInfoHelper.ResolveFileLinkTarget(String filePath) in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\Internal\FileSystemInfoHelper.cs:line 34
     at Microsoft.Extensions.FileProviders.Physical.PollingWildCardChangeToken.GetLastWriteUtc(String path) in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\PollingWildCardChangeToken.cs:line 147
     at Microsoft.Extensions.FileProviders.Physical.PollingWildCardChangeToken.CalculateChanges() in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\PollingWildCardChangeToken.cs:line 115
     at Microsoft.Extensions.FileProviders.Physical.PollingWildCardChangeToken.get_HasChanged() in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\PollingWildCardChangeToken.cs:line 98
     at Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.RaiseChangeEvents(Object state) in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\PhysicalFilesWatcher.cs:line 437
     at System.Threading.TimerQueueTimer.CallCallback(Boolean isThreadPool) in System.Private.CoreLib.dll:token 0x600303a+0x2b
     at System.Threading.TimerQueueTimer.Fire(Boolean isThreadPool) in System.Private.CoreLib.dll:token 0x6003038+0x3b
     at System.Threading.TimerQueue.FireNextTimers() in System.Private.CoreLib.dll:token 0x6002d9e+0x1a9
     at System.Threading.TimerQueue.AppDomainTimerCallback(Int32 id) in System.Private.CoreLib.dll:token 0x6002d95+0x0

I suspect is because of the following (even though I am getting the error when calling CreateFileW):

// Files that are marked for deletion will not let you GetFileAttributes,
// ERROR_ACCESS_DENIED is given back without filling out the data struct.
// FindFirstFile, however, will. Historically we always gave back attributes
// for marked-for-deletion files.

I wasn't able to create a unit case that consistently could hit this issue but by always returning null when the LinkTarget property hits an error, we can mitigate the issue.
In addition, this can make developer's life easier by not being afraid of such property breaking their app.

This also grants us parity with the Unix implementation.

@jozkee jozkee added this to the 6.0.0 milestone Jul 14, 2021
@jozkee jozkee self-assigned this Jul 14, 2021
@ghost
Copy link

ghost commented Jul 14, 2021

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

Issue Details

Motivated by #55664. When I was testing that PR, I noticed that I was getting ACCESS DENIED errors sporadically, here's the callstack:

  Unhandled exception. System.UnauthorizedAccessException: Access to the path 'C:\Users\david\AppData\Local\Temp\tapmbdam.rgw\4d2sb45x.hix_FOO_True' is denied.
     at System.IO.FileSystem.GetImmediateLinkTarget(String linkPath, Boolean isDirectory, Boolean throwOnUnreachable, Boolean returnFullPath) in System.Private.CoreLib.dll:token 0x6005ec9+0x3b
     at System.IO.FileSystem.GetLinkTarget(String linkPath, Boolean isDirectory) in System.Private.CoreLib.dll:token 0x6005ec8+0x0
     at System.IO.FileSystemInfo.get_LinkTarget() in System.Private.CoreLib.dll:token 0x6005ee2+0xf
     at Microsoft.Extensions.FileProviders.Physical.FileSystemInfoHelper.ResolveFileLinkTarget(FileInfo fileInfo) in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\Internal\FileSystemInfoHelper.cs:line 44
     at Microsoft.Extensions.FileProviders.Physical.FileSystemInfoHelper.ResolveFileLinkTarget(String filePath) in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\Internal\FileSystemInfoHelper.cs:line 34
     at Microsoft.Extensions.FileProviders.Physical.PollingWildCardChangeToken.GetLastWriteUtc(String path) in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\PollingWildCardChangeToken.cs:line 147
     at Microsoft.Extensions.FileProviders.Physical.PollingWildCardChangeToken.CalculateChanges() in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\PollingWildCardChangeToken.cs:line 115
     at Microsoft.Extensions.FileProviders.Physical.PollingWildCardChangeToken.get_HasChanged() in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\PollingWildCardChangeToken.cs:line 98
     at Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.RaiseChangeEvents(Object state) in C:\repos\runtime\src\libraries\Microsoft.Extensions.FileProviders.Physical\src\PhysicalFilesWatcher.cs:line 437
     at System.Threading.TimerQueueTimer.CallCallback(Boolean isThreadPool) in System.Private.CoreLib.dll:token 0x600303a+0x2b
     at System.Threading.TimerQueueTimer.Fire(Boolean isThreadPool) in System.Private.CoreLib.dll:token 0x6003038+0x3b
     at System.Threading.TimerQueue.FireNextTimers() in System.Private.CoreLib.dll:token 0x6002d9e+0x1a9
     at System.Threading.TimerQueue.AppDomainTimerCallback(Int32 id) in System.Private.CoreLib.dll:token 0x6002d95+0x0

I suspect is because of the following (even though I am getting the error when calling CreateFileW):

// Files that are marked for deletion will not let you GetFileAttributes,
// ERROR_ACCESS_DENIED is given back without filling out the data struct.
// FindFirstFile, however, will. Historically we always gave back attributes
// for marked-for-deletion files.

I wasn't able to create a unit case that consistently could hit this issue but by always returning null when the LinkTarget property hits an error, we can mitigate the issue.
In addition, this can make developer's life easier by not being afraid of such property breaking their app.

This also grants us parity with the Unix implementation.

Author: Jozkee
Assignees: Jozkee
Labels:

area-System.IO

Milestone: 6.0.0

@@ -600,13 +604,15 @@ uint GetFinalPathNameByHandle(SafeFileHandle handle, char[] buffer)
{
// Since all these paths will be passed to CreateFile, which takes a string anyway, it is pointless to use span.
// I am not sure if it's possible to change CreateFile's param to ROS<char> and avoid all these allocations.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also follow-up to address this comment? If we can save allocations by marshaling a span instead of creating a string to then pass down, we should. You can't today pass a span directly to a DllImport method, but you can manually pin it and pass in the pointer, which is exactly what the runtime does with string.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will address this in a separate PR in order to get this in before the preview7 snap, thanks.

@jozkee jozkee merged commit 71d0d2b into dotnet:main Jul 15, 2021
@jozkee jozkee deleted the relax_linktarget branch July 15, 2021 16:52
@ghost ghost locked as resolved and limited conversation to collaborators Aug 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants