Skip to content

dyn Allocator together with Allocator + Clone requirements is unsound, leading to UB with Arc #156920

Closed

Description

@maxdexh

View all comments

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
}

cc #156882, #156906

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on May 25, 2026
  2. maxdexh commented on May 25, 2026

    @maxdexh
    MemberAuthor

    I guess Allocator can either not be dyn-compatible or we will need a dedicated unsafe trait AllocatorClone :(

  3. Darksonn commented on May 25, 2026

    @Darksonn
    Member

    I guess #156917 and this issue just illustrate that doing this:

    /// # Safety
    /// If this type also implements `MySafeTrait`, then the implementation must satisfy
    /// XYZ conditions to avoid UB.
    unsafe trait MyUnsafeTrait {}
    
    trait MySafeTrait {}

    is fundamentally only possible if MyUnsafeTrait is not dyn compatible.

  4. maxdexh commented on May 25, 2026

    @maxdexh
    MemberAuthor

    Pretty much, yeah. This particular case could be kind of avoided if Box<A: Allocator> and &mut A don't impl Allocator, but that seems extremely fragile.

  5. maxdexh commented on May 25, 2026

    @maxdexh
    MemberAuthor

    Safety guarantees like this would probably also be extremely dangerous with specialization.

  6. Darksonn commented on May 25, 2026

    @Darksonn
    Member

    @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 Allocator dyn compatible.

  7. maxdexh commented on May 25, 2026

    @maxdexh
    MemberAuthor

    If someone tries to make Allocator dyn compatible.

    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.

  8. changed the title [-]`dyn Allocator` together with `Allocator + Clone` requirements is unsound[/-] [+]`dyn Allocator` together with `Allocator + Clone` requirements is unsound, leading to UB with `Arc`[/+] on May 25, 2026
  9. added
    T-libs-api[DEPRECATED; DO NOT USE]
    I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
    requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.
    A-dyn-traitArea: trait objects, vtable layout
    A-dyn-compatibilityArea: Dyn compatibility (formerly: object safety)
    on May 25, 2026
  10. 150 remaining items

  11. added
    I-lang-radarItems that are on lang's radar and will need eventual work or consideration.
    on Jun 10, 2026
  12. added 3 commits that reference this issue on Jul 7, 2026
  13. added a commit that references this issue on Jul 8, 2026
  14. linked a pull request that will close this issueallocator: refactor for stabilisation #157428on Jul 17, 2026
  15. added
    T-libsRelevant to the library team, which will review and decide on the PR/issue.
    and removed
    T-libs-api[DEPRECATED; DO NOT USE]
    on Aug 12, 2026
  16. added a commit that references this issue on Sep 23, 2026
  17. added a commit that references this issue on Sep 23, 2026
  18. added a commit that references this issue on Oct 1, 2026
  19. added a commit that references this issue on Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-allocatorsArea: Custom and system allocatorsA-boxArea: Our favorite opsem complicationA-coherenceArea: CoherenceA-dyn-compatibilityArea: Dyn compatibility (formerly: object safety)A-dyn-traitArea: trait objects, vtable layoutC-bugCategory: This is a bug.I-lang-radarItems 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/SoundnessT-libsRelevant 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.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions