From 2900f162b37ba47b8bcb9b87e9e2de1cf2254a6a Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Fri, 18 Jun 2021 09:17:52 -0400 Subject: [PATCH] rust: kernel: add missing safety comments - Add safety comment to usage of get_unused_fd_flags - Add documentation and safety comments to internal open_callback helper function - Add additional safety documentation to FileOpenAdapter::convert Signed-off-by: Dan Robertson --- rust/kernel/file.rs | 1 + rust/kernel/file_operations.rs | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/rust/kernel/file.rs b/rust/kernel/file.rs index 262a856fc4910f..10c0c133ae8a85 100644 --- a/rust/kernel/file.rs +++ b/rust/kernel/file.rs @@ -95,6 +95,7 @@ pub struct FileDescriptorReservation { impl FileDescriptorReservation { /// Creates a new file descriptor reservation. pub fn new(flags: u32) -> Result { + // SAFETY: FFI call, there are no safety requirements on `flags`. let fd = unsafe { bindings::get_unused_fd_flags(flags) }; if fd < 0 { return Err(Error::from_kernel_errno(fd)); diff --git a/rust/kernel/file_operations.rs b/rust/kernel/file_operations.rs index 7891a61695089f..65027add798def 100644 --- a/rust/kernel/file_operations.rs +++ b/rust/kernel/file_operations.rs @@ -79,13 +79,29 @@ pub enum SeekFrom { Current(i64), } +/// Called by the VFS when an inode should be opened. +/// +/// Calls `T::open` on the returned value of `A::convert`. +/// +/// # Safety +/// +/// The returned value of `A::convert` must be a valid non-null pointer and +/// `T:open` must return a valid non-null pointer on an `Ok` result. unsafe extern "C" fn open_callback>( inode: *mut bindings::inode, file: *mut bindings::file, ) -> c_types::c_int { from_kernel_result! { + // SAFETY: `A::convert` must return a valid non-null pointer that + // should point to data in the inode or file that lives longer + // than the following use of `T::open`. let arg = unsafe { A::convert(inode, file) }; + // SAFETY: `arg` was previously returned by `A::convert` and must + // be a valid non-null pointer. let ptr = T::open(unsafe { &*arg })?.into_pointer(); + // SAFETY: `ptr` was previously returned by `T::open`. The returned + // value should be a boxed value and should live the length of the + // given file. unsafe { (*file).private_data = ptr as *mut c_types::c_void }; Ok(0) } @@ -500,7 +516,8 @@ pub trait FileOpenAdapter { /// # Safety /// /// This function must be called only when [`struct file_operations::open`] is being called for - /// a file that was registered by the implementer. + /// a file that was registered by the implementer. The returned pointer must be valid and + /// not-null. unsafe fn convert(_inode: *mut bindings::inode, _file: *mut bindings::file) -> *const Self::Arg; }