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

libstd: support creation of anonymous pipe on WinXP/2K3 #37677

Merged
merged 1 commit into from
Nov 21, 2016
Merged

libstd: support creation of anonymous pipe on WinXP/2K3 #37677

merged 1 commit into from
Nov 21, 2016

Conversation

jsen-
Copy link
Contributor

@jsen- jsen- commented Nov 10, 2016

PIPE_REJECT_REMOTE_CLIENTS flag is not supported on Windows < VISTA, and every invocation of anon_pipe including attempts to pipe std::process::Child's stdio fails.
This PR should work around this issue by performing a runtime check of windows version and conditionally omitting this flag on "XP and friends".

Getting the version should be probably moved out of the function anon_pipe itself (the OS version does not often change during runtime :) ), but:

  • I didn't find any precedent for this and assuming there's not much overhead (I hope windows does not perform any heuristics to find out it's own version, just fills couple of fields in the struct).
  • the code path is not especially performance sensitive anyway.

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @brson (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

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

Looks good to me, thanks!

@@ -809,6 +810,16 @@ pub enum EXCEPTION_DISPOSITION {
ExceptionCollidedUnwind
}

#[repr(C)]
pub struct OSVERSIONINFO {
pub dwOSVersionInfoSize: DWORD,
Copy link
Member

Choose a reason for hiding this comment

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

Could this use 4-space tabs?

@xen0n
Copy link
Contributor

xen0n commented Nov 10, 2016

Isn't this opening a security hole on these platforms, as the flag is presumably there for literally preventing remote connections to the pipes created? The correct behavior seems doable on those legacy systems though, albeit only with some ACL tricks, and I don't know if we really should go this far to support Tier-3 platforms like that.

@xen0n
Copy link
Contributor

xen0n commented Nov 10, 2016

Also, the GetVersionExW function is:

  • neither heuristics-free (its behavior depends on existence of app manifest, at least),
  • nor guaranteed to work under future releases of Windows,

so IMO this may require some degree of rethink. At least the version check could be unnecessary if we simply go ahead creating, checking GetLastError in case of failure and retrying with the compatible method if it's actually due to not supporting the flag.

@jsen-
Copy link
Contributor Author

jsen- commented Nov 10, 2016

@xen0n you're right, I missassumed the possible performance implication of GetVersionExW it should be at least moved outside of the function, but the truth is, retrying on Parameter is incorrect error should cover this better - this is easy

I can even try to hack something in the spirit of the linked SO answer later today, but I'm by no means a winapi expert

@alexcrichton sorry, didn't notice - rustfmt stopped working for me a while back and I haven't attempted to resurrect it yet, will fix in the next commit

@alexcrichton
Copy link
Member

@xen0n's solution also sounds fine by me (try the current strategy and fall back if that fails). I'd be fine punting on ACL business and whatnot, XP is only Tier 3 after all

@xen0n
Copy link
Contributor

xen0n commented Nov 10, 2016

@alexcrichton Sure, XP is Tier 3 and ACL is a lot of unneeded complexity, but IMO the security implication should at least be documented. People are bound to leverage the compatibility if it's there, and (incorrectly) expect the security level to be the same as the Tier-1 Windows versions. Although XP users' problems are much deeper than some under-protected pipes could bring about, I certainly don't think Rust should take the blame in case the introduced inconsistent behavior actually leads to exploits.

@sfackler
Copy link
Member

Windows XP hasn't received security updates for over 2 years.

@xen0n
Copy link
Contributor

xen0n commented Nov 10, 2016

@sfackler Yeah, sure. XP's overall security won't get any better even if we implemented the correct behavior, and since it's unsupported not documenting the inconsistency is perfectly acceptable as well. I'd then suggest putting a comment about the decision and forget about it. 😂

@alexcrichton alexcrichton added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Nov 10, 2016
}

let sid_world_auth = c::SECURITY_WORLD_SID_AUTHORITY;
let mut world_sid: *mut c_void = ptr::null_mut();
Copy link
Contributor Author

@jsen- jsen- Nov 18, 2016

Choose a reason for hiding this comment

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

TODO: when to free the memory pointed to by world_sid, network_sid and psd?

@jsen-
Copy link
Contributor Author

jsen- commented Nov 18, 2016

Alright, I made a rough draft of how it might look like...
Tests on i686-pc-windows-gnu passed fine on my machine, but I have no idea how or whether it is even possible to somehow run the tests on WinXP (except that my code using it still works there after this change).

!!!Currently the code leaks memory!!! so it's not ready for prime time, but I'd like to ask for help from someone more experienced with this winapi stuff.
My basic question is when is it safe to free the pointers allocated by AllocateAndInitializeSid and LocalAlloc (is it safe to free right after the pipe was created or after not being used anymore?).

I believe the code is not very idiomatic rust, so all comments are very welcome.
Most of the attributes on FFI imports were guesswork, so it definitely needs attention as well.

@alexcrichton
Copy link
Member

@jsen- I think @sfackler's got a good point that guaranteeing the same semantics here is probably the last of one's "security concerns" on XP. In that sense what do you think of the strategy of attempting to pass the flag, and then trying to not pass the flag if that fails with a particular error? (for XP)

@jsen-
Copy link
Contributor Author

jsen- commented Nov 18, 2016

@alexcrichton fully agree, I think this PR got a little overkill for what the issue deserves. Let me shake of some of it's weight
I'll try to push an update when I'm back from work

@jsen-
Copy link
Contributor Author

jsen- commented Nov 19, 2016

Here's the original simple version minus windows version check. Relying on CreateNamedPipeW with PIPE_REJECT_REMOTE_CLIENTS returning ERROR_INVALID_PARAMETER on XP as suggested by @xen0n.
Note added to the documentation.

@alexcrichton
Copy link
Member

Thanks! Looks good to me, but I think we can remove the note for XP users. We typically don't have this sort of platform-specific notes in the docs just yet, and this is a bit prominent for something that's relevant to very few people.

@xen0n
Copy link
Contributor

xen0n commented Nov 19, 2016

Putting the note (preferably along with justification of security reduction) in code comment should be enough IMO.

@jsen-
Copy link
Contributor Author

jsen- commented Nov 19, 2016

Removed the note from documentation and added code comment with implications and justification.
Sorry for the number of commits, I tried squashing some, but it seems to have just added more and more (poor git skills indeed)

@xen0n
Copy link
Contributor

xen0n commented Nov 20, 2016

@jsen- Don't worry and just use git rebase -i <your upstream remote>/master for the nice fixups!

@alexcrichton
Copy link
Member

Ah yeah code looks good to me, and with a squash I'd r+. Let me know if you need help squashing though

@jsen-
Copy link
Contributor Author

jsen- commented Nov 20, 2016

okay I think it's good now, thanks for patience :)

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented Nov 21, 2016

📌 Commit fc5a361 has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented Nov 21, 2016

⌛ Testing commit fc5a361 with merge 7b3eeea...

bors added a commit that referenced this pull request Nov 21, 2016
libstd: support creation of anonymous pipe on WinXP/2K3

`PIPE_REJECT_REMOTE_CLIENTS` flag is not supported on Windows < VISTA, and every invocation of `anon_pipe` including attempts to pipe `std::process::Child`'s stdio fails.
This PR should work around this issue by performing a runtime check of windows version and conditionally omitting this flag on "XP and friends".

Getting the version should be probably moved out of the function `anon_pipe` itself (the OS version does not often change during runtime :) ), but:
 - I didn't find any precedent for this and assuming there's not much overhead (I hope windows does not perform any heuristics to find out it's own version, just fills couple of fields in the struct).
 - the code path is not especially performance sensitive anyway.
@bors bors merged commit fc5a361 into rust-lang:master Nov 21, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants