Skip to content

Windows env::set_current_dir / chdir does not reject interior NUL before SetCurrentDirectoryW #597

Description

@SebTardif

Summary

library/std/src/sys/paths/windows.rs chdir builds the wide path with encode_wide() plus only a trailing 0, without rejecting interior NULs. SetCurrentDirectoryW treats the buffer as a C-style wide string, so an embedded 0 truncates the path and changes the current directory to an unintended prefix.

Most other Windows path entry points route through to_u16s / ensure_no_nuls (e.g. sys/path/windows.rs helpers, AF_UNIX, junction fixes).

Origin

Audit of external-input trust boundaries in std (Windows path / 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/paths/windows.rs#L106-L112

pub fn chdir(p: &path::Path) -> io::Result<()> {
    let p: &OsStr = p.as_ref();
    let mut p = p.encode_wide().collect::<Vec<_>>();
    p.push(0);
    cvt(unsafe { c::SetCurrentDirectoryW(p.as_ptr()) }).map(drop)
}

Suggested fix

Use to_u16s(p)? which rejects interior NULs and appends the terminator.

Impact

Low-to-medium. Requires a path with an embedded NUL in the OsStr (possible via untrusted OsString bytes on Windows). Misbehavior is wrong cwd / unexpected path resolution, 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