Skip to content

Implementing From<&mut AsciiStr> for &mut str and &mut [u8] is unsound #64

@tormol

Description

@tormol

They allow writing non-ASCII values to an AsciiStr which when read out as an AsciiChar will produce values outside the valid niche.

These impls were added by me in 4fbd050, so 0.9, 0.8 and 0.7 are affected.

Here's an example using these impls to create out-of-bounds array indexing in safe code (when compiled in release mode):

let mut buf = [0u8; 1];
let ascii = buf.as_mut_ascii_str().unwrap();
let byte_view = <&mut[u8] as From<&mut AsciiStr>>::from(ascii);
let arr = [0b11011101u8; 128];
byte_view[0] = 180;
assert_ne!(arr[ascii[0] as u8 as usize], 0b11011101);

I don't see any good way to tell users of the crate to stop using these impls:
Deprecation notices on trait impls are ignored (by both Rust 1.38 and Rust 1.9).
Changing the impls to panic or return an empty slice could break working code (that never writes non-ASCII values) at run-time.

The only fix we could make appears to be to remove the impls, telling users of them to do the unsafe pointer casting explicitly. On one hand this will make any accidental users of it aware of the problem when they update Cargo.lock, but it will also break any use that happened to be OK with a minor release, and any reverse dependencies of these uses.
On the other hand doing nothing and hoping nobody accidentally uses these impls feels irresponsible. What do you think @tomprogrammer?
In any case I don't think we need to fix 0.7 and 0.8, as Rust didn't backport the security fix in 1.29.1 to previous affected versions.

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