Repository navigation
dyn Allocator together with Allocator + Clone requirements is unsound, leading to UB with Arc #156920
Copy link
Copy link
Closed
Labels
A-allocatorsArea: Custom and system allocatorsArea: Custom and system allocatorsA-boxArea: Our favorite opsem complicationArea: Our favorite opsem complicationA-coherenceArea: CoherenceArea: CoherenceA-dyn-compatibilityArea: Dyn compatibility (formerly: object safety)Area: Dyn compatibility (formerly: object safety)A-dyn-traitArea: trait objects, vtable layoutArea: trait objects, vtable layoutC-bugCategory: This is a bug.Category: This is a bug.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Description
Part 2! This time featuring Clone instead of PartialEq. This one is way worse because Arc relies on it.
#![feature(allocator_api)]
use std::{
alloc::{Allocator, Global, System},
sync::Arc,
};
pub trait NewTrait: Allocator {}
impl<A: Allocator> NewTrait for A {}
impl Clone for Box<dyn NewTrait> { // valid because Box is special and `dyn NewTrait` is a local type
fn clone(&self) -> Self {
// safe clone impl that violates the safety
// requirements of Allocator because now,
// `Self: Allocator + Clone`, but the clone is incompatible
Box::new(System)
}
}
use jemallocator::Jemalloc;
#[global_allocator]
static GLOBAL: Jemalloc = Jemalloc;
fn main() {
let evil_arc = Arc::new_in(69420, Box::new(Global) as Box<dyn NewTrait>);
let wat = evil_arc.clone(); // clone() returns the wrong allocator
drop(evil_arc);
drop(wat); // free(): invalid pointer
}Reacted by Alice Ryhl, Predrag Gruevski, Aurelia Molzer, Nia Deckers, Jana Dönszelmann and teor
Metadata
Metadata
Assignees
Labels
A-allocatorsArea: Custom and system allocatorsArea: Custom and system allocatorsA-boxArea: Our favorite opsem complicationArea: Our favorite opsem complicationA-coherenceArea: CoherenceArea: CoherenceA-dyn-compatibilityArea: Dyn compatibility (formerly: object safety)Area: Dyn compatibility (formerly: object safety)A-dyn-traitArea: trait objects, vtable layoutArea: trait objects, vtable layoutC-bugCategory: This is a bug.Category: This is a bug.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Activity
maxdexh commentedon May 25, 2026
I guess
Allocatorcan either not bedyn-compatible or we will need a dedicatedunsafe trait AllocatorClone:(Darksonn commentedon May 25, 2026
I guess #156917 and this issue just illustrate that doing this:
is fundamentally only possible if
MyUnsafeTraitis not dyn compatible.maxdexh commentedon May 25, 2026
Pretty much, yeah. This particular case could be kind of avoided if
Box<A: Allocator>and&mut Adon't implAllocator, but that seems extremely fragile.maxdexh commentedon May 25, 2026
Safety guarantees like this would probably also be extremely dangerous with specialization.
Darksonn commentedon May 25, 2026
@maxdexh Please open a PR to add these examples as compile-fail tests. This ensures we do not forget about them in the future if someone tries to make
Allocatordyn compatible.maxdexh commentedon May 25, 2026
Non
dyn-compatibility is not the only option here. The alternative (which I would honestly prefer since these requirements are also succeptible to future language additions) is a dedicated unsafe Clone trait for allocators.[-]`dyn Allocator` together with `Allocator + Clone` requirements is unsound[/-][+]`dyn Allocator` together with `Allocator + Clone` requirements is unsound, leading to UB with `Arc`[/+]150 remaining items
Rollup merge of rust-lang#157801 - theemathas:allocator-safety-rewrit…
Rollup merge of rust-lang#157801 - theemathas:allocator-safety-rewrit…
Rollup merge of rust-lang#157801 - theemathas:allocator-safety-rewrit…
Unrolled build for #157801
Rollup merge of rust-lang#156882 - nia-e:stable-allocator, r=clarfonthey
Unrolled build for #156882 in rollup 163189
Rollup merge of #156882 - nia-e:stable-allocator, r=clarfonthey
Rollup merge of rust-lang#156882 - nia-e:stable-allocator, r=clarfonthey
Rollup merge of rust-lang#156882 - nia-e:stable-allocator, r=clarfonthey