FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

host_env: Reject interior NULs for CreateProcessW by joshuamegnauth54 · Pull Request #8555 · RustPython/RustPython · GitHub

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .rs  (1) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
60 changes: 23 additions & 37 deletions crates/host_env/src/winapi.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ pub fn create_file_w(
/// `startup_info` must point to a valid `STARTUPINFOW` (or extended).
unsafe fn create_process_w_raw(
app_name: Option<&widestring::WideCStr>,
command_line: Option<&mut [u16]>,
command_line: Option<&mut widestring::WideCStr>,
inherit_handles: i32,
creation_flags: u32,
env: Option<&[u16]>,
Expand All @@ -214,37 +214,6 @@ unsafe fn create_process_w_raw(
Ok(unsafe { procinfo.assume_init() })
}

/// Win32 `CreateProcessW` requires `lpCommandLine` to be NUL-terminated.
/// The buffer is passed `&mut [u16]` because `CreateProcessW` may modify it
/// in place.
#[inline]
fn validate_command_line_terminated(buf: &[u16]) -> io::Result<()> {
if buf.last() == Some(&0) {
Ok(())
} else {
Err(io::Error::new(
io::ErrorKind::InvalidInput,
"command_line buffer passed to create_process must be NUL-terminated",
))
}
}

/// Win32 `CreateProcessW` with `CREATE_UNICODE_ENVIRONMENT` requires
/// `lpEnvironment` to be a sequence of `KEY=value\0` strings followed by a
/// final terminating `\0` — i.e. the block ends with two consecutive zero
/// `u16`s.
#[inline]
fn validate_environment_block_terminated(buf: &[u16]) -> io::Result<()> {
if buf.len() >= 2 && buf[buf.len() - 2..] == [0, 0] {
Ok(())
} else {
Err(io::Error::new(
io::ErrorKind::InvalidInput,
"env block passed to create_process must end with a double NUL terminator",
))
}
}

#[allow(
clippy::too_many_arguments,
reason = "This is the semantic host wrapper for Win32 CreateProcess parameters."
Expand All @@ -259,11 +228,28 @@ pub fn create_process(
startup_info: StartupInfoData,
handle_list: Option<Vec<usize>>,
) -> io::Result<ProcessInfo> {
if let Some(cmd) = command_line.as_deref() {
validate_command_line_terminated(cmd)?;
}
if let Some(env_block) = env {
validate_environment_block_terminated(env_block)?;
// Win32 `CreateProcessW` requires `lpCommandLine` to be NUL-terminated.
// The buffer is passed `&mut [u16]` because `CreateProcessW` may modify it in place.
let command_line = command_line
.map(widestring::WideCStr::from_slice_mut)
.transpose()
.map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidInput,
"command_line buffer passed to create_process must be NUL-terminated",
)
})?;
// Win32 `CreateProcessW` with `CREATE_UNICODE_ENVIRONMENT` requires
// `lpEnvironment` to be a sequence of `KEY=value\0` strings followed by a
// final terminating `\0` — i.e. the block ends with two consecutive zero
// `u16`s.
if let Some(env_block) = env
&& !env_block.ends_with(&[0, 0])
{
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"env block passed to create_process must end with a double NUL terminator",
));
}

let mut si: windows_sys::Win32::System::Threading::STARTUPINFOEXW =
Expand Down
Loading

Back | FazBrowse Home | New Git URL