From 8615daab29b2b481196ba7702fb46111c3615b55 Mon Sep 17 00:00:00 2001 From: Jakob Buchgraber Date: Thu, 11 Jan 2024 01:57:05 -0800 Subject: [PATCH] #rust #unsafe Fix unsound cast of RepeatedMut to RepeatedView When we implement Deref for RepeatedMut we cast it to a RepeatedView. The safety comments state that this is sound because both RepeatdView and RepeatedMut are repr(transparent) over InnerRepeatedMut. However, this has no longer been true after a recent change. RepeatedView and RepeatedMut had different layouts. This change fixes the soundness issue by type casting the RawRepeatedField of a RepeatedMut to a RepeatedView. This is sound because RepeatedReview is repr(transparent) over RawRepeatedField. PiperOrigin-RevId: 597488476 --- rust/repeated.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/rust/repeated.rs b/rust/repeated.rs index 91ef0ae2d4..00b827d2b5 100644 --- a/rust/repeated.rs +++ b/rust/repeated.rs @@ -46,7 +46,6 @@ impl<'msg, T: ?Sized> Debug for RepeatedView<'msg, T> { } /// Mutates the elements in a `repeated` field of `T`. -#[repr(transparent)] pub struct RepeatedMut<'msg, T: ?Sized> { pub(crate) inner: InnerRepeatedMut<'msg>, _phantom: PhantomData<&'msg mut T>, @@ -58,12 +57,9 @@ impl<'msg, T: ?Sized> Deref for RepeatedMut<'msg, T> { type Target = RepeatedView<'msg, T>; fn deref(&self) -> &Self::Target { // SAFETY: - // - `Repeated{View,Mut}<'msg, T>` are both `#[repr(transparent)]` over - // `RepeatedField<'msg, T>`. - // - `Repeated{View,Mut}<'msg, T>` are both `#[repr(transparent)]` over - // `RepeatedField<'msg, T>`. - // - `RepeatedField` is a type alias for `NonNull`. - unsafe { &*(self as *const Self as *const RepeatedView<'msg, T>) } + // - `RepeatedView<'msg, T>` is `#[repr(transparent)]` over + // `RawRepeatedField`. + unsafe { &*(&self.inner.raw as *const RawRepeatedField as *const RepeatedView<'msg, T>) } } }