Skip to content

Add UserSlicePtrWriter::write. #171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 8, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions rust/kernel/user_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should all the "reads" in this paragraph be "writes"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant reading the memory contents (before writing). I updated the comment, hopefully it's clearer now. PTAL.

///
/// # 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.
///
Expand Down Expand Up @@ -246,4 +271,11 @@ impl UserSlicePtrWriter {
self.1 -= len;
Ok(())
}

/// Writes the contents of the given data into the user slice.
pub fn write<T: WritableToBytes>(&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::<T>()) }
}
}