Skip to content

deny transmute of &[T] into &[U] where U is larger than T #10285

@KisaragiEffective

Description

@KisaragiEffective

What it does

This prevents a kind of UB.

Examples:

let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];
let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
// expected to be expanded
assert_eq!(alt_slice[0], 1);
assert_eq!(alt_slice[1], 2);
assert_eq!(alt_slice[2], 3);
assert_eq!(alt_slice[3], 4);

This is not true. alt_slice[0] have (mostly) 0x01020304 or 0x04030201 depending on byte-order, and left is looks like garbage and user thinks it is not what (s)he wanted.

Also, this contains UB. Miri reports call to transmute is UB.

I believe: mem::transmute::<&[T], &[U]> is UB if and only if mem::size_of<T> < mem::size_of<U>.

Alternatives:

This may not be MachineApplicable, because:
If user is expected to keep length and transmute each element:

// let original_slice: &[T] = ...
let alt_slice: &[U] = original_slice
    .iter()
    .map(|original| unsafe { core::mem::transmute(original) })
    .collect::<Vec<_>>()
    .as_slice()

If user is expected to transmute entire bit pattern of pointing bit-pattern:

// let original_slice: &[T] = ...
let (prefix, align_result, suffix) = original_slice.align_to::<U>();
assert_eq!(prefix.len(), 0);
assert_eq!(suffix.len(), 0);

Lint Name

transmute_to_larger_element_slice

Category

correctness

Advantage

  • Prevents a kind of UB.

Drawbacks

No response

Example

// let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];
let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };

Could be written as:

let alt_slice: &[u32] = original_slice
    .iter()
    .map(|original| unsafe { core::mem::transmute(original) })
    .collect::<Vec<_>>()
    .as_slice()

or

let (prefix, align_result, suffix) = original_slice.align_to::<u32>();
assert_eq!(prefix.len(), 0);
assert_eq!(suffix.len(), 0);

Metadata

Metadata

Labels

A-lintArea: New lints

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions