From 23fe859a8ae1b4d7c0052d6207fe1ed6b696c855 Mon Sep 17 00:00:00 2001 From: JunRyoung Ju Date: Fri, 7 Apr 2023 17:40:28 +0900 Subject: [PATCH 1/2] Fix-up soundness hole --- src/lib.rs | 28 ++++++++++++++++++++++++---- src/utils.rs | 20 ++++++++++++-------- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4383d2a..8f2ba37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -81,13 +81,19 @@ where } /// get pinned mutable referencial object that has self lifetime. - pub fn pin_mut<'s>(self: Pin<&'s mut Self>) -> Pin<&'s mut R::Type<'s>> { + pub fn pin_mut<'s, 'x>(self: Pin<&'s mut Self>) -> Pin<&'s mut R::Type<'x>> + where + 'x: 'a, + { let referential = self.project().referential; unsafe { detach_lifetime_pin_mut::(referential) } } /// get pinned referencial object that has self lifetime. - pub fn pin_ref<'s>(self: Pin<&'s Self>) -> Pin<&'s R::Type<'s>> { + pub fn pin_ref<'s, 'x>(self: Pin<&'s Self>) -> Pin<&'s R::Type<'x>> + where + 'x: 'a, + { let referential = self.project_ref().referential; unsafe { detach_lifetime_pin_ref::(referential) } } @@ -137,15 +143,29 @@ where } } - pub fn get_ref<'s>(&'s self) -> &'s R::Type<'s> { + pub fn get_ref<'s, 'x>(&'s self) -> &'s R::Type<'x> + where + 'x: 'a, + { unsafe { detach_lifetime_get_ref::(&self.referential) } } /// get mutable reference from stable referential object. - pub fn get_mut<'s>(&'s mut self) -> &'s mut R::Type<'s> { + pub fn get_mut<'s, 'x>(&'s mut self) -> &'s mut R::Type<'x> + where + 'x: 'a, + { unsafe { detach_lifetime_get_mut::(&mut self.referential) } } + pub fn with_mut<'s, F, V>(&'s mut self, f: F) -> V + where + for<'this> F: FnOnce(&'s mut R::Type<'this>) -> V, + { + let r = unsafe { detach_lifetime_get_mut::(&mut self.referential) }; + f(r) + } + pub fn into_inner(self) -> T { self.object } diff --git a/src/utils.rs b/src/utils.rs index e51175e..643d48e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -19,7 +19,9 @@ where } #[inline] -pub unsafe fn detach_lifetime_get_ref<'this, R: ?Sized>(v: &'this R::Type<'_>) -> &'this R::Type<'this> +pub unsafe fn detach_lifetime_get_ref<'x, 'y, 'z: 'y, R: ?Sized>( + v: &'x R::Type<'y>, +) -> &'x R::Type<'z> where R: RefDef, { @@ -32,7 +34,9 @@ where } #[inline] -pub unsafe fn detach_lifetime_get_mut<'this, R: ?Sized>(v: &'this mut R::Type<'_>) -> &'this mut R::Type<'this> +pub unsafe fn detach_lifetime_get_mut<'x, 'y, 'z: 'y, R: ?Sized>( + v: &'x mut R::Type<'y>, +) -> &'x mut R::Type<'z> where R: RefDef, { @@ -45,9 +49,9 @@ where } #[inline] -pub unsafe fn detach_lifetime_pin_mut<'this, R: ?Sized>( - v: Pin<&mut R::Type<'_>>, -) -> Pin<&'this mut R::Type<'this>> +pub unsafe fn detach_lifetime_pin_mut<'x, 'y, 'z: 'y, R: ?Sized>( + v: Pin<&'x mut R::Type<'y>>, +) -> Pin<&'x mut R::Type<'z>> where R: RefDef, { @@ -55,9 +59,9 @@ where } #[inline] -pub unsafe fn detach_lifetime_pin_ref<'this, R: ?Sized>( - v: Pin<&R::Type<'_>>, -) -> Pin<&'this R::Type<'this>> +pub unsafe fn detach_lifetime_pin_ref<'x, 'y, 'z: 'y, R: ?Sized>( + v: Pin<&'x R::Type<'y>>, +) -> Pin<&'x R::Type<'z>> where R: RefDef, { From ec0c3b2f3a26809feb565078ca428f97c697d383 Mon Sep 17 00:00:00 2001 From: JunRyoung Ju Date: Fri, 7 Apr 2023 17:53:46 +0900 Subject: [PATCH 2/2] Fix-up soundness issue --- src/lib.rs | 38 ++++++++------------------------------ src/utils.rs | 51 --------------------------------------------------- 2 files changed, 8 insertions(+), 81 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8f2ba37..af01066 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -81,21 +81,13 @@ where } /// get pinned mutable referencial object that has self lifetime. - pub fn pin_mut<'s, 'x>(self: Pin<&'s mut Self>) -> Pin<&'s mut R::Type<'x>> - where - 'x: 'a, - { - let referential = self.project().referential; - unsafe { detach_lifetime_pin_mut::(referential) } + pub fn pin_mut<'s>(self: Pin<&'s mut Self>) -> Pin<&'s mut R::Type<'a>> { + self.project().referential } /// get pinned referencial object that has self lifetime. - pub fn pin_ref<'s, 'x>(self: Pin<&'s Self>) -> Pin<&'s R::Type<'x>> - where - 'x: 'a, - { - let referential = self.project_ref().referential; - unsafe { detach_lifetime_pin_ref::(referential) } + pub fn pin_ref<'s>(self: Pin<&'s Self>) -> Pin<&'s R::Type<'a>> { + self.project_ref().referential } } @@ -143,27 +135,13 @@ where } } - pub fn get_ref<'s, 'x>(&'s self) -> &'s R::Type<'x> - where - 'x: 'a, - { - unsafe { detach_lifetime_get_ref::(&self.referential) } + pub fn get_ref<'s>(&'s self) -> &'s R::Type<'a> { + &self.referential } /// get mutable reference from stable referential object. - pub fn get_mut<'s, 'x>(&'s mut self) -> &'s mut R::Type<'x> - where - 'x: 'a, - { - unsafe { detach_lifetime_get_mut::(&mut self.referential) } - } - - pub fn with_mut<'s, F, V>(&'s mut self, f: F) -> V - where - for<'this> F: FnOnce(&'s mut R::Type<'this>) -> V, - { - let r = unsafe { detach_lifetime_get_mut::(&mut self.referential) }; - f(r) + pub fn get_mut<'s>(&'s mut self) -> &'s mut R::Type<'a> { + &mut self.referential } pub fn into_inner(self) -> T { diff --git a/src/utils.rs b/src/utils.rs index 643d48e..c194a15 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,7 +1,6 @@ use crate::refs::RefDef; use core::mem; -use core::pin::Pin; // SAFETY-NOTE: we are trasmutting same type with different lifetime, unless lifetime // based generic speialization is on stable this is always safe. @@ -17,53 +16,3 @@ where return value; } - -#[inline] -pub unsafe fn detach_lifetime_get_ref<'x, 'y, 'z: 'y, R: ?Sized>( - v: &'x R::Type<'y>, -) -> &'x R::Type<'z> -where - R: RefDef, -{ - // I don't know why rustc indicates that different lifetime with same type has different size. - // we are just using trasmute_copy and forget instead of transmute. - let value = mem::transmute_copy(&v); - mem::forget(v); - - return value; -} - -#[inline] -pub unsafe fn detach_lifetime_get_mut<'x, 'y, 'z: 'y, R: ?Sized>( - v: &'x mut R::Type<'y>, -) -> &'x mut R::Type<'z> -where - R: RefDef, -{ - // I don't know why rustc indicates that different lifetime with same type has different size. - // we are just using trasmute_copy and forget instead of transmute. - let value = mem::transmute_copy(&v); - mem::forget(v); - - return value; -} - -#[inline] -pub unsafe fn detach_lifetime_pin_mut<'x, 'y, 'z: 'y, R: ?Sized>( - v: Pin<&'x mut R::Type<'y>>, -) -> Pin<&'x mut R::Type<'z>> -where - R: RefDef, -{ - mem::transmute(v) -} - -#[inline] -pub unsafe fn detach_lifetime_pin_ref<'x, 'y, 'z: 'y, R: ?Sized>( - v: Pin<&'x R::Type<'y>>, -) -> Pin<&'x R::Type<'z>> -where - R: RefDef, -{ - mem::transmute(v) -}