From 297850a677e1daa48746a61de909cbe8d483fd28 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 12 Feb 2024 21:24:48 +0000 Subject: [PATCH] Add more checks for pointers with vtable meta The rules for casting `*mut X` -> `*mut Y` are as follows: - If `B` has a principal - `A` must have exactly the same principal (including generics) - Auto traits of `B` must be a subset of autotraits in `A` Note that `X<_>` and `Y<_>` can be identity, or arbitrary structs with last field being the dyn type. The lifetime of the trait object itself (`dyn ... + 'a`) is not checked. This prevents a few soundness issues with `#![feature(arbitrary_self_types)]` and trait upcasting. Namely, these checks make sure that vtable is always valid for the pointee. --- alloc/src/boxed.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/alloc/src/boxed.rs b/alloc/src/boxed.rs index 1ec095a46f704..65bcb241e4aec 100644 --- a/alloc/src/boxed.rs +++ b/alloc/src/boxed.rs @@ -2374,7 +2374,7 @@ impl dyn Error + Send { let err: Box = self; ::downcast(err).map_err(|s| unsafe { // Reapply the `Send` marker. - Box::from_raw(Box::into_raw(s) as *mut (dyn Error + Send)) + mem::transmute::, Box>(s) }) } } @@ -2387,8 +2387,8 @@ impl dyn Error + Send + Sync { pub fn downcast(self: Box) -> Result, Box> { let err: Box = self; ::downcast(err).map_err(|s| unsafe { - // Reapply the `Send + Sync` marker. - Box::from_raw(Box::into_raw(s) as *mut (dyn Error + Send + Sync)) + // Reapply the `Send + Sync` markers. + mem::transmute::, Box>(s) }) } }