Auto merge of #58216 - pitdicker:sqos_flags, r=alexcrichton
Set secure flags when opening a named pipe on Windows Fixes https://github.com/rust-lang/rust/issues/42036, see also the previous attempt in https://github.com/rust-lang/rust/pull/44556. Whether this is correct depends on if it is somehow possible to create a symlink to a named pipe, outside the named pipe filesystem (NPFS). But as far as I can tell that should be impossible. Also fixes that `security_qos_flags(SECURITY_ANONYMOUS)` does not set the `SECURITY_SQOS_PRESENT` flag, and the incorrect documentation about the default value of `security_qos_flags`.
This commit is contained in:
commit
fab272e5ef
2 changed files with 24 additions and 7 deletions
|
@ -220,13 +220,27 @@ pub trait OpenOptionsExt {
|
||||||
/// the specified value (or combines it with `custom_flags` and `attributes`
|
/// the specified value (or combines it with `custom_flags` and `attributes`
|
||||||
/// to set the `dwFlagsAndAttributes` for [`CreateFile`]).
|
/// to set the `dwFlagsAndAttributes` for [`CreateFile`]).
|
||||||
///
|
///
|
||||||
/// By default, `security_qos_flags` is set to `SECURITY_ANONYMOUS`. For
|
/// By default `security_qos_flags` is not set. It should be specified when
|
||||||
/// information about possible values, see [Impersonation Levels] on the
|
/// opening a named pipe, to control to which degree a server process can
|
||||||
/// Windows Dev Center site.
|
/// act on behalf of a client process (security impersonation level).
|
||||||
///
|
///
|
||||||
|
/// When `security_qos_flags` is not set a malicious program can gain the
|
||||||
|
/// elevated privileges of a privileged Rust process when it allows opening
|
||||||
|
/// user-specified paths, by tricking it into opening a named pipe. So
|
||||||
|
/// arguably `security_qos_flags` should also be set when opening arbitrary
|
||||||
|
/// paths. However the bits can then conflict with other flags, specifically
|
||||||
|
/// `FILE_FLAG_OPEN_NO_RECALL`.
|
||||||
|
///
|
||||||
|
/// For information about possible values, see [Impersonation Levels] on the
|
||||||
|
/// Windows Dev Center site. The `SECURITY_SQOS_PRESENT` flag is set
|
||||||
|
/// automatically when using this method.
|
||||||
|
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
|
/// # #[cfg(for_demonstration_only)]
|
||||||
|
/// extern crate winapi;
|
||||||
|
/// # mod winapi { pub const SECURITY_IDENTIFICATION: u32 = 0; }
|
||||||
/// use std::fs::OpenOptions;
|
/// use std::fs::OpenOptions;
|
||||||
/// use std::os::windows::prelude::*;
|
/// use std::os::windows::prelude::*;
|
||||||
///
|
///
|
||||||
|
@ -235,9 +249,9 @@ pub trait OpenOptionsExt {
|
||||||
/// .create(true)
|
/// .create(true)
|
||||||
///
|
///
|
||||||
/// // Sets the flag value to `SecurityIdentification`.
|
/// // Sets the flag value to `SecurityIdentification`.
|
||||||
/// .security_qos_flags(1)
|
/// .security_qos_flags(winapi::SECURITY_IDENTIFICATION)
|
||||||
///
|
///
|
||||||
/// .open("foo.txt");
|
/// .open(r"\\.\pipe\MyPipe");
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
|
/// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
|
||||||
|
|
|
@ -191,7 +191,11 @@ impl OpenOptions {
|
||||||
pub fn access_mode(&mut self, access_mode: u32) { self.access_mode = Some(access_mode); }
|
pub fn access_mode(&mut self, access_mode: u32) { self.access_mode = Some(access_mode); }
|
||||||
pub fn share_mode(&mut self, share_mode: u32) { self.share_mode = share_mode; }
|
pub fn share_mode(&mut self, share_mode: u32) { self.share_mode = share_mode; }
|
||||||
pub fn attributes(&mut self, attrs: u32) { self.attributes = attrs; }
|
pub fn attributes(&mut self, attrs: u32) { self.attributes = attrs; }
|
||||||
pub fn security_qos_flags(&mut self, flags: u32) { self.security_qos_flags = flags; }
|
pub fn security_qos_flags(&mut self, flags: u32) {
|
||||||
|
// We have to set `SECURITY_SQOS_PRESENT` here, because one of the valid flags we can
|
||||||
|
// receive is `SECURITY_ANONYMOUS = 0x0`, which we can't check for later on.
|
||||||
|
self.security_qos_flags = flags | c::SECURITY_SQOS_PRESENT;
|
||||||
|
}
|
||||||
pub fn security_attributes(&mut self, attrs: c::LPSECURITY_ATTRIBUTES) {
|
pub fn security_attributes(&mut self, attrs: c::LPSECURITY_ATTRIBUTES) {
|
||||||
self.security_attributes = attrs as usize;
|
self.security_attributes = attrs as usize;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +243,6 @@ impl OpenOptions {
|
||||||
self.custom_flags |
|
self.custom_flags |
|
||||||
self.attributes |
|
self.attributes |
|
||||||
self.security_qos_flags |
|
self.security_qos_flags |
|
||||||
if self.security_qos_flags != 0 { c::SECURITY_SQOS_PRESENT } else { 0 } |
|
|
||||||
if self.create_new { c::FILE_FLAG_OPEN_REPARSE_POINT } else { 0 }
|
if self.create_new { c::FILE_FLAG_OPEN_REPARSE_POINT } else { 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue