From b6da36fc30399ecbef834ef589246d5ac87d0aab Mon Sep 17 00:00:00 2001 From: Wedson Almeida Filho Date: Thu, 8 Apr 2021 11:47:26 +0100 Subject: [PATCH 1/2] Add `UserSlicePtrWriter::write`. --- rust/kernel/user_ptr.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/rust/kernel/user_ptr.rs b/rust/kernel/user_ptr.rs index d9d91bcdbfa983..6fb03188f9dfae 100644 --- a/rust/kernel/user_ptr.rs +++ b/rust/kernel/user_ptr.rs @@ -46,6 +46,31 @@ unsafe impl ReadableFromBytes for i32 {} unsafe impl ReadableFromBytes for i64 {} unsafe impl ReadableFromBytes for isize {} +/// Specifies that a type can be safely writable to byte slices. +/// +/// This means that we don't read undefined values when reading the memory contents (which leads to +/// UB). It also ensures that no potentially sensitive information is leaked into the byte slices. +/// +/// # Safety +/// +/// A type must not include padding bytes and must be fully initialsed to safely implement +/// [`WritableToBytes`] (i.e., it doesn't contain [`MaybeUninit`] fields). A composition of +/// writable types in a structure is not necessarily writable because it may result in padding +/// bytes. +pub unsafe trait WritableToBytes {} + +// SAFETY: Initialised instances of the following types have no uninitialised portions. +unsafe impl WritableToBytes for u8 {} +unsafe impl WritableToBytes for u16 {} +unsafe impl WritableToBytes for u32 {} +unsafe impl WritableToBytes for u64 {} +unsafe impl WritableToBytes for usize {} +unsafe impl WritableToBytes for i8 {} +unsafe impl WritableToBytes for i16 {} +unsafe impl WritableToBytes for i32 {} +unsafe impl WritableToBytes for i64 {} +unsafe impl WritableToBytes for isize {} + /// A reference to an area in userspace memory, which can be either /// read-only or read-write. /// @@ -246,4 +271,11 @@ impl UserSlicePtrWriter { self.1 -= len; Ok(()) } + + /// Writes the contents of the given data into the user slice. + pub fn write(&mut self, data: &T) -> KernelResult<()> { + // SAFETY: The input buffer is valid as it's coming from a live + // reference to a type that implements `WritableToBytes`. + unsafe { self.write_raw(data as *const T as _, size_of::()) } + } } From ef7b3ff6ae39aab6be9c5cb7f4a488154ae21652 Mon Sep 17 00:00:00 2001 From: Wedson Almeida Filho Date: Thu, 8 Apr 2021 13:23:21 +0100 Subject: [PATCH 2/2] Improve comments. --- rust/kernel/user_ptr.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rust/kernel/user_ptr.rs b/rust/kernel/user_ptr.rs index 6fb03188f9dfae..812a37b39d3b20 100644 --- a/rust/kernel/user_ptr.rs +++ b/rust/kernel/user_ptr.rs @@ -46,14 +46,15 @@ unsafe impl ReadableFromBytes for i32 {} unsafe impl ReadableFromBytes for i64 {} unsafe impl ReadableFromBytes for isize {} -/// Specifies that a type can be safely writable to byte slices. +/// Specifies that a type is safely writable to byte slices. /// -/// This means that we don't read undefined values when reading the memory contents (which leads to -/// UB). It also ensures that no potentially sensitive information is leaked into the byte slices. +/// This means that we don't read undefined values (which leads to UB) in preparation for writing +/// to the byte slice. It also ensures that no potentially sensitive information is leaked into the +/// byte slices. /// /// # Safety /// -/// A type must not include padding bytes and must be fully initialsed to safely implement +/// A type must not include padding bytes and must be fully initialised to safely implement /// [`WritableToBytes`] (i.e., it doesn't contain [`MaybeUninit`] fields). A composition of /// writable types in a structure is not necessarily writable because it may result in padding /// bytes.