PipeOptions.CurrentUserOnly incorrectly uses WindowsIdentity.GetCurrent().Owner to get the current user SID
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
### Description
The Windows implementation of PipeOptions.CurrentUserOnly incorrectly uses WindowsIdentity.GetCurrent().**Owner** to get the current **user** SID. It should be using WindowsIdentity.GetCurrent().**User** to get the current user SID. This results in unexpected authorization failures when connecting to a process with the same user SID but different owner SIDs. The owner SID is the identity of who created the process, not the identity of the process itself, and is thus inappropriate to use for PipeOptions.CurrentUserOnly.
The bug exists in both NamedPipeClientStream and NamedPipeServerStream:
https://github.com/dotnet/runtime/blob/main/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs
https://github.com/dotnet/runtime/blob/main/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Windows.cs
### Reproduction Steps
I encountered this bug when trying to connect between two processes running as SYSTEM. The client process was created from an admin user process, so its owner was Administrators, and the server process was a Windows Service (created by the SCM), so its owner was SYSTEM. Both processes had a user SID of SYSTEM and thus should have been able to connect with PipeOptions.CurrentUserOnly, but couldn't connect because they had different owner SIDs (which should be irrelevant for PipeOptions.CurrentUserOnly).
### Expected behavior
Processes with the same user SID should be able to connect with PipeOptions.CurrentUserOnly even if their owner SIDs don't match.
### Actual behavior
Processes using PipeOptions.CurrentUserOnly can only connect if their owner SIDs match. Otherwise, they get an authorization error. Owner SIDs should be irrelevant for the intended and documented behavior of PipeOptions.CurrentUserOnly.
### Regression?
No, this has been implemented incorrectly since PipeOptions.CurrentUserOnly was introduced in .NET Core in 2018.
### Known Workarounds
I was able to work around the issue by removing the PipeOptions.CurrentUserOnly flag and instead copy-pasted the implementation of PipeOptions.CurrentUserOnly into my client and server and replaced WindowsIdentity.GetCurrent().**Owner** with WindowsIdentity.GetCurrent().**User**. To make the fix in .NET is a trivial find-and-replace of "Owner" with "User" in two places (one in NamedPipeClientStream and one in NamedPipeServerStream).
### Configuration
I was testing with .NET 8 on Windows 11 (x64) but the bug exists in the source code since PipeOptions.CurrentUserOnly was introduced in .NET Core in 2018.
### Other information
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.