Skip to content

Windows make_command_line copies argv0 without rejecting interior NUL #595

Description

@SebTardif

Summary

library/std/src/sys/process/windows.rs make_command_line encodes the program name (argv0) with encode_wide() directly into the CreateProcessW command line. Individual arguments go through args::append_arg, which calls ensure_no_nuls, but argv0 does not.

An OsStr program name containing an interior wide 0 is therefore truncated when Windows parses the command line, while the intended path after the NUL is dropped. make_envp and make_dirp in the same module already reject NULs via ensure_no_nuls.

Origin

Audit of external-input trust boundaries in std (Windows process spawn / WinAPI string helpers), SebTardif/rust fork of rust-lang/rust.

Affected code (upstream tip at audit time)

https://github.com/rust-lang/rust/blob/f28ac764c36/library/std/src/sys/process/windows.rs#L861-L880

fn make_command_line(argv0: &OsStr, args: &[Arg], force_quotes: bool) -> io::Result<Vec<u16>> {
    ...
    cmd.push(b'"' as u16);
    cmd.extend(argv0.encode_wide());  // no ensure_no_nuls(argv0)
    cmd.push(b'"' as u16);
    for arg in args {
        ...
        args::append_arg(&mut cmd, arg, force_quotes)?;  // checks NULs
    }
}

Suggested fix

Call ensure_no_nuls(argv0)? before encoding, matching make_envp / make_dirp and args::append_arg.

Impact

Low-to-medium. Requires a caller to pass an OsStr with an embedded NUL as Command::new / program path (possible via OsString from untrusted bytes on Windows). Misbehavior is truncated spawn path / wrong process, not memory unsafety in safe Rust.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions