lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241009014810.23279-1-christiansantoslima21@gmail.com>
Date: Tue,  8 Oct 2024 22:47:50 -0300
From: Christian dos Santos de Lima <christiansantoslima21@...il.com>
To: rust-for-linux@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Miguel Ojeda <ojeda@...nel.org>,
	Alex Gaynor <alex.gaynor@...il.com>,
	Boqun Feng <boqun.feng@...il.com>,
	Gary Guo <gary@...yguo.net>,
	Björn Roy Baron <bjorn3_gh@...tonmail.com>,
	Benno Lossin <benno.lossin@...ton.me>,
	Andreas Hindborg <a.hindborg@...nel.org>,
	Alice Ryhl <aliceryhl@...gle.com>,
	Trevor Gross <tmgross@...ch.edu>
Subject: [PATCH] rust: transmute: Add implementation for FromBytes trait

Add implementation and documentation for FromBytes trait.

Add new feature block in order to allow using ToBytes
and bound to from_bytes_mut function.

Link: https://github.com/Rust-for-Linux/linux/issues/1119
Signed-off-by: Christian dos Santos de Lima <christiansantoslima21@...il.com>
---
 rust/kernel/lib.rs       |   2 +
 rust/kernel/transmute.rs | 302 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 290 insertions(+), 14 deletions(-)

diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index dc37aef6a008..5215f5744e12 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -18,6 +18,8 @@
 #![feature(lint_reasons)]
 #![feature(new_uninit)]
 #![feature(unsize)]
+#![feature(portable_simd)]
+#![feature(trivial_bounds)]
 
 // Ensure conditional compilation based on the kernel configuration works;
 // otherwise we may silently break things like initcall handling.
diff --git a/rust/kernel/transmute.rs b/rust/kernel/transmute.rs
index 1c7d43771a37..f2d99c136017 100644
--- a/rust/kernel/transmute.rs
+++ b/rust/kernel/transmute.rs
@@ -12,24 +12,298 @@
 /// # Safety
 ///
 /// All bit-patterns must be valid for this type. This type must not have interior mutability.
-pub unsafe trait FromBytes {}
+pub unsafe trait FromBytes {
+    ///Converts a slice of Bytes into a Reference to Self
+    ///
+    /// # Examples
+    /// ```
+    ///    pub unsafe trait FromBytes {
+    ///        unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self;
+    ///        unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    ///        where
+    ///            Self: ToBytes;
+    ///    }
+    ///
+    ///unsafe impl FromBytes for u32 {
+    ///    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+    ///        let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+    ///        &*slice_ptr
+    ///    }
+    ///
+    ///    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    ///    where
+    ///        Self: ToBytes,
+    ///    {
+    ///        let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+    ///        &mut *slice_ptr
+    ///    }
+    ///}
+    ///
+    ///let slice_of_bytes : &[u8] = &[1, 2, 3, 4];
+    ///let result = u32::from_bytes(slice_of_bytes);
+    ///assert_eq!(*result, 0x4030201);
+    ///```
+    ///# Safety
+    ///
+    ///Guarantee that all values are initiliazed
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self;
+    ///Converts a mutabble slice of Bytes into a mutable Reference to Self
+    /// # Safety
+    ///
+    /// ToBytes in order to allow only types that implements ToBytes
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes;
+}
 
-macro_rules! impl_frombytes {
-    ($($({$($generics:tt)*})? $t:ty, )*) => {
-        // SAFETY: Safety comments written in the macro invocation.
-        $(unsafe impl$($($generics)*)? FromBytes for $t {})*
-    };
+// SAFETY: All bit patterns are acceptable values of the types below.
+unsafe impl FromBytes for u8 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
 }
 
-impl_frombytes! {
-    // SAFETY: All bit patterns are acceptable values of the types below.
-    u8, u16, u32, u64, usize,
-    i8, i16, i32, i64, isize,
+unsafe impl FromBytes for u16 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for u32 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for u64 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for usize {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for i8 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for i16 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for i32 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for i64 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for isize {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+// SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
+// patterns are also acceptable for arrays of that type.
+unsafe impl<T: FromBytes> FromBytes for [T] {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const T;
+            let slice_len = slice_of_bytes.len() / core::mem::size_of::<T>();
+            core::slice::from_raw_parts(slice_ptr, slice_len)
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut T;
+            let slice_len = slice_of_bytes.len() / core::mem::size_of::<T>();
+            core::slice::from_raw_parts_mut(slice_ptr, slice_len)
+        }
+    }
+}
+
+/// # Examples
+///```
+///let slice_of_bytes: &[u8] = &[
+///    1, 0, 0, 0,
+///    2, 0, 0, 0,
+///    3, 0, 0, 0,
+///    4, 0, 0, 0,
+///    5, 0, 0, 0,
+///    6, 0, 0, 0,
+///    7, 0, 0, 0,
+///    8, 0, 0, 0,
+///];
+///
+///let foo = <[u32; 8]>::from_bytes(slice_of_bytes);
+///let expected: [u32; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
+///
+///assert_eq!(*foo, expected);
+///```
+unsafe impl<T: FromBytes, const N: usize> FromBytes for [T; N] {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const T;
+            &*(slice_ptr as *const [T; N])
+        }
+    }
 
-    // SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
-    // patterns are also acceptable for arrays of that type.
-    {<T: FromBytes>} [T],
-    {<T: FromBytes, const N: usize>} [T; N],
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *mut T;
+            &mut *(slice_ptr as *mut [T; N])
+        }
+    }
 }
 
 /// Types that can be viewed as an immutable slice of initialized bytes.
-- 
2.46.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ