Skip to content

Padding can create objects larger than isize::MAX bytes #117265

Closed
@LegionMammal978

Description

rustc generally detects when a static type is larger than isize::MAX bytes, giving an error that values of the type `...` are too big for the current architecture. However, if a type has fields at most isize::MAX bytes long, and additional padding that brings it to isize::MAX + 1 bytes, then this error will not be generated. To illustrate, all four of these print 0x80000000 (i.e., isize::MAX + 1):

// cargo build --release --target i686-unknown-linux-gnu
// prlimit --stack=unlimited target/i686-unknown-linux-gnu/release/example

use std::{hint, mem::{self, MaybeUninit}, alloc::Layout};

#[repr(C, align(2))]
struct Example(MaybeUninit<[u8; 0x7fffffff]>);

fn main() {
    println!("{:#x}", mem::size_of::<Example>());
    println!("{:#x}", Layout::new::<Example>().size());

    let e = Example(MaybeUninit::uninit());
    hint::black_box(&e);
    println!("{:#x}", mem::size_of_val(&e));
    println!("{:#x}", Layout::for_value(&e).size());
}

(The black_box() is to ensure that an object of size 0x80000000 is actually created on the stack.)

This is clearly unsound, since it breaks the size invariant of Layout, and since third-party crates may depend on types being no larger than isize::MAX for soundness. However, it's nontrivial to observe unexpected behavior from this using only safe APIs in the standard library, since placing the overlarge type within any other type, even a repr(transparent) wrapper, will result in a compile error as expected, and the standard APIs tend to refer to &[T; 1] when creating a slice from a reference.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-layoutArea: Memory layout of typesC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions