-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
“Attempted to perform an unauthorized operation” when calling NamedPipeServerStream.SetAccessControl #26400
Comments
I noticed that the tests for the extension methods all use the empty Sure enough, if I pass in an empty
From what I know about Named Pipes, when you create them, you can pass in a Security object that will create all the ACLs you want but you can't update them once created. This means that SetAccessControl probably won't work for NamedPipes. In the .NET Framework, there was a ctor for I'm really hoping there's some sort of solution for this out in the wild as I need it in .NET Core 2.0 - otherwise I'll have to go down the pinvoke route to create a Pipe that way. |
A think the main reason is that the ACLs feature currently not implemented in UNIX variant NamedPipeServer implementation. This SO post also about this problem: I also hope this feature will be implemented in the near future. |
I appreciate the response but the limitation I pointed out is on Windows which I would expect to work with Pipe Security. Unix is important as well, but that to me is an additional feature, not a bug like this issue is :) |
@pjanotti @weshaggard do you know why |
@danmosemsft your correct that it wasn't included because of layering issues. NamedPipeServerStream is part of .NET Standard but the ACL API's are not so this member was excluded from the standard and here in the core. |
Talked offline, part of the problem is that ACL's are not even part of the base shared package so having NPSS reference ACL's pulls a lot of code into the core install. @pjanotti hopefully can help brainstorm possible solutions for what you want to do. |
Hi @tylerl0706 - Windows docs state that should be possible, but I gave a few tries and couldn't do it too - I'll have to investigate it more. Is the new feature |
@tylerl0706 you won't be able to do without p/invoke since you need to specify something like @danmosemsft I am getting under the impression that The feature request to support |
@pjanotti I don't know. The original commit suggests PipeSecurity is expected to work. Hopefully you can figure out the history and missing pieces. |
Looking at the history it should never worked since the rights flags were never set when calling CreateNamedPipe (since 1st version on the repo). |
One possible way to make this work is to add to S.IO.Pipes.AccessControl some static factory methods that can create named pipes with OTOH S.IO.Pipes.AccessControl seems to never ever actually worked with anything other than the empty @tylerl0706 if you can provide some more info about your scenario and what you are trying to achieve? It can be a helpful data point. /cc @danmosemsft @stephentoub @weshaggard @safern |
The constructors that are related to AccessControl and could be covered in the package for matching functionality with Fx are: namespace System.IO.Pipes
{
public sealed class AnonymousPipeServerStream : PipeStream
{
public AnonymousPipeServerStream(PipeDirection direction, HandleInheritability inheritability, int bufferSize, PipeSecurity pipeSecurity);
}
public sealed class NamedPipeClientStream : PipeStream
{
public NamedPipeClientStream(string serverName, string pipeName, PipeAccessRights desiredAccessRights, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability);
}
public sealed class NamedPipeServerStream : PipeStream
{
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights);
}
} Note that only one of them shows some usage in apisof.net: 0.10 of nuget packages for |
I ended up going the p/invoke route and borrowed most of the code from PowerShell... It's ugly... But at least our pipes are secure. |
Thanks for reporting back. I am under the impression that |
@tylerl0706 as you probably know 2.0 will go out of support in 2 1/2 months - Oct 1st so perhaps you can move to |
@danmosemsft PowerShell Editor Services (which powers things like the vscode PowerShell extension) is dependent on whatever version of PowerShell the user is using. Since PowerShell Core 6.0.0 shipped with .NET Core 2.0.X, we will have to support .NET Core 2.0.X until we're ready to drop PowerShell 6.0.0 support in the vscode extension (maybee after 6.1.0 is released which is on Core 2.1... Need to talk to @Steve_MSFT some more about though). |
Thanks all for the quick responses. I really appreciate it! |
Notice that |
Yeah. I'm looking to target .NET Standard because this library gets loaded into Windows PowerShell (.NET Framework based) and PowerShell Core (.NET Core based) |
Just a general comment, and please ignore if foolish as I am a complete newbie to core and standard. Lack of ACL support (or a consistent replacement) in .netstandard seems problematic to me. I've just had a try at porting a medium sized communications library written in .net framework and it all went fairly painlessly until security. Named mutexs, memory mapped files, and named pipes, all need an ACL on windows to prevent userland privilege escalation, and that issue is going to be there on any OS. It just seems a little perverse that the only way I could get things to work right now is to turn off security. I'd like to target .netstandard through most of our components, but IPC mechanisms are at the base of the stack, and if they can't be secured, they can't be used, and the whole house of cards falls down. That's a long winded way of saying, please add CurrentUserOnly to standard .next. Ideally all these constructors that went missing with the security Param would come back. In magical unicorn land there would be an object security abstraction that would work across platforms. I'm very very ignorant, but surely the concept of users, roles and permissions crosses platforms. The ACL just seems so pivotal to security on windows that it came as a shock that the replacement is either missing, or not obvious, in .net standard. CurrentUserOnly is much better than nothing. At least this prevents a trust boundary violation. |
Thanks for the feedback @l-o-l and @tylerl0706. I will start the steps to get |
@pjanotti I have a couple questions about
|
Yes it does work cross plat. In Windows we use ACL and in Unix we use PeerID to get the socket's owner ID and check if it is the same user trying to connect:
Yes it does, in Windows ACL will handle this by itself, and in Unix whenever you elevate you're now a different user (root) so the PeerID and current user ID should differ. Just as a guide this are the tests for this feature: |
Fantastic. I'd use that in a heartbeat if it was available in .NET Standard. |
Straight to the relevant comment in the PR on dotnet/standard https://github.com/dotnet/standard/pull/826/files#r202885532 |
Sorry for hijacking this thread a little bit. There's a pending issue in Mono to import System.IO.Pipes from CoreFX. I've update the pull request from last year and this resulted in the following API diff: https://jenkins.mono-project.com/job/test-mono-pull-request-amd64/16144//Public_20API_20Diff/ In essence we are missing the ACL constructors mentioned above. They can't be effectively added using the existing API surface since it would not behave the same on Windows, where the PipeSecurity is used when creating the pipe handle. What would be the correct way to proceed with a proposal to add these APIs back? Should I open an issue for it? Since System.IO.Pipes.AccessControl was already merged into System.IO.Pipes there would be no additional dependency. |
@filipnavara for my understanding: do you need these constructors back to keep the API surface unchanged? What is Mono behavior with these constructors outside of Windows? (Ignore not supported parameters? Throw PNSE? Something else?). |
@pjanotti At the moment Mono completely lacks the pipe implementation on non-Windows platforms and throws NotImplementedException for most calls. My current plan is to throw PNSE on non-Windows platforms for these additional constructors on Unix and restore NetFX behavior on Windows. |
More specifically, I am currently fiddling with approach that throws PNSE only if non-default values are used in the parameters. |
@filipnavara the issue is that the types needed for those constructors are not exposed from the ref, if we bring back those constructors we will have to make the types public again. However, at this moment, they only make sense for Windows and are not part of .NET Standard so I don't think we should bring them back, since they already do nothing on Mono there shouldn't be anybody using them. If someone is porting code from Fx the main use for these constructors should be replaced by the Is it a deal breaker, for importing CoreFx, removing these constructors from Mono? If yes, why? |
I assumed the types are exposed in ref (https://github.com/dotnet/corefx/blob/master/src/System.IO.Pipes.AccessControl/ref/System.IO.Pipes.AccessControl.cs), although in different assembly. It seems the CoreFX code already references the types in System.IO.Pipes though only in an extension class. The current Mono code implements the constructors, but they only work on Windows (the whole System.IO.Pipes code does). The desktop API profile of Mono is tracking the NetFX API. Thus removing the constructors would be a regression and it would also break the API compatibility (which is checked against reference assemblies). I came up with a solution to use the CoreFX code and at the same time provide the constructors on all Mono supported platforms. I just need a little bit of the internals exposed (pull request dotnet/corefx#31118). Then I can implement the rest as |
System.IO.Pipes.AccessControl is a package that is not shipped with CoreFx, so those types are only exposed if one explicit imports the package, that's why we don't want to expose those constructors directly in CoreFx. I took a very quick glance at your changes and it seems fine since you are not exposing any net public constructor or type - as you said the constructors will be done on Mono partial classes. The overall thing is good since it will bring /cc @marek-safar |
Closing this one and tracking issue regarding System.IO.Pipes.AccessControl package at https://github.com/dotnet/corefx/issues/31190 |
I'm having some trouble securing a NamedPipeServerStream from a .NET Standard lib. I opened a question on stack overflow here.
The gist is that when I try to call SetAccessControl using either of the listed ways, I get an "Attempted to perform an unauthorized operation":
PipesAclExtensions.SetAccessControl(pipeServer, pipeSecurity);
pipeServer.SetAccessControl(pipeSecurity);
Here's a gist of the problem.
The exception I'm getting is:
NOTE: I am pulling in the System.IO.Pipes.AccessControl nuget package
Am I doing something wrong?
The text was updated successfully, but these errors were encountered: