Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

const_heap feature can be used to leak mutable memory into final value of constant #129233

Open
RalfJung opened this issue Aug 18, 2024 · 0 comments
Labels
A-const-eval Area: constant evaluation (mir interpretation) F-const_heap `#[feature(const_heap)]` F-const_mut_refs `#![feature(const_mut_refs)]` F-core_intrinsics Issue in the "core intrinsics" for internal usage only. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. P-low Low priority requires-incomplete-features

Comments

@RalfJung
Copy link
Member

RalfJung commented Aug 18, 2024

Consider this code:

#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_mut_refs)]
use std::intrinsics;

const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };

fn main() {}

This code is problematic because when BAR is used multiple times in the program, it will always point to the same global allocation, violating the idea that consts behave as-if their initializer is inlined everywhere they are used. Furthermore, under our current interning strategy this allocation will end up being immutable in the runtime phase of the program, so writing it is UB, which could be quite surprising.

We have a safety net in the interner that catches this problem, but the safety net has a big gaping hole around shared references with interior mutability, and can hence easily be circumvented:

#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_mut_refs, const_refs_to_cell)]

use std::intrinsics;
use std::cell::Cell;

const BAR: *mut i32 = unsafe {
    let launder = &*(intrinsics::const_allocate(4, 4) as *const Cell<i32>);
    launder as *const _ as *mut i32
};

fn main() {}

The gaping hole in the safety net is needed due to #121610 and rust-lang/unsafe-code-guidelines#493; also see the description of #128543 for more context.

This seems like a pretty major blocker for the const_heap feature, unless we want to just declare this UB "ex machina".

Cc @rust-lang/wg-const-eval
(Not something to be discussed any time soon, I am filing this because tidy forced me to have an issue number for the ICE that ensues from this mutable-ref-escape-prevention-bypass.)

@RalfJung RalfJung added the A-const-eval Area: constant evaluation (mir interpretation) label Aug 18, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Aug 18, 2024
@lolbinarycat lolbinarycat added requires-incomplete-features F-const_mut_refs `#![feature(const_mut_refs)]` F-core_intrinsics Issue in the "core intrinsics" for internal usage only. F-const_heap `#[feature(const_heap)]` P-low Low priority labels Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: constant evaluation (mir interpretation) F-const_heap `#[feature(const_heap)]` F-const_mut_refs `#![feature(const_mut_refs)]` F-core_intrinsics Issue in the "core intrinsics" for internal usage only. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. P-low Low priority requires-incomplete-features
Projects
None yet
Development

No branches or pull requests

3 participants