Commit db4f72c9 authored by Miguel Ojeda's avatar Miguel Ojeda
Browse files

rust: enable `clippy::undocumented_unsafe_blocks` lint

Checking that we are not missing any `// SAFETY` comments in our `unsafe`
blocks is something we have wanted to do for a long time, as well as
cleaning up the remaining cases that were not documented [1].

Back when Rust for Linux started, this was something that could have
been done via a script, like Rust's `tidy`. Soon after, in Rust 1.58.0,
Clippy implemented the `undocumented_unsafe_blocks` lint [2].

Even though the lint has a few false positives, e.g. in some cases where
attributes appear between the comment and the `unsafe` block [3], there
are workarounds and the lint seems quite usable already.

Thus enable the lint now.

We still have a few cases to clean up, so just allow those for the moment
by writing a `TODO` comment -- some of those may be good candidates for
new contributors.

Link: https://github.com/Rust-for-Linux/linux/issues/351 [1]
Link: https://rust-lang.github.io/rust-clippy/master/#/undocumented_unsafe_blocks [2]
Link: https://github.com/rust-lang/rust-clippy/issues/13189

 [3]
Reviewed-by: default avatarAlice Ryhl <aliceryhl@google.com>
Reviewed-by: default avatarTrevor Gross <tmgross@umich.edu>
Tested-by: default avatarGary Guo <gary@garyguo.net>
Reviewed-by: default avatarGary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20240904204347.168520-5-ojeda@kernel.org


Signed-off-by: default avatarMiguel Ojeda <ojeda@kernel.org>
parent 567cdff5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -457,6 +457,7 @@ export rust_common_flags := --edition=2021 \
			    -Wclippy::needless_bitwise_bool \
			    -Wclippy::needless_continue \
			    -Wclippy::no_mangle_with_rust_abi \
			    -Wclippy::undocumented_unsafe_blocks \
			    -Wrustdoc::missing_crate_level_docs

KBUILD_HOSTCFLAGS   := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \
+1 −0
Original line number Diff line number Diff line
@@ -17,5 +17,6 @@ pub extern "C" fn kasan_test_rust_uaf() -> u8 {
    }
    let ptr: *mut u8 = addr_of_mut!(v[2048]);
    drop(v);
    // SAFETY: Incorrect, on purpose.
    unsafe { *ptr }
}
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
)]

#[allow(dead_code)]
#[allow(clippy::undocumented_unsafe_blocks)]
mod bindings_raw {
    // Use glob import here to expose all helpers.
    // Symbols defined within the module will take precedence to the glob import.
+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ pub(crate) unsafe fn krealloc_aligned(ptr: *mut u8, new_layout: Layout, flags: F
    unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags.0) as *mut u8 }
}

// SAFETY: TODO.
unsafe impl GlobalAlloc for KernelAllocator {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety
@@ -39,6 +40,7 @@ unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
    }

    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
        // SAFETY: TODO.
        unsafe {
            bindings::kfree(ptr as *const core::ffi::c_void);
        }
+6 −3
Original line number Diff line number Diff line
@@ -171,9 +171,11 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.name() {
            // Print out number if no name can be found.
            None => f.debug_tuple("Error").field(&-self.0).finish(),
            // SAFETY: These strings are ASCII-only.
            Some(name) => f
                .debug_tuple(unsafe { core::str::from_utf8_unchecked(name) })
                .debug_tuple(
                    // SAFETY: These strings are ASCII-only.
                    unsafe { core::str::from_utf8_unchecked(name) },
                )
                .finish(),
        }
    }
@@ -277,6 +279,8 @@ pub(crate) fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> {
    if unsafe { bindings::IS_ERR(const_ptr) } {
        // SAFETY: The FFI function does not deref the pointer.
        let err = unsafe { bindings::PTR_ERR(const_ptr) };

        #[allow(clippy::unnecessary_cast)]
        // CAST: If `IS_ERR()` returns `true`,
        // then `PTR_ERR()` is guaranteed to return a
        // negative value greater-or-equal to `-bindings::MAX_ERRNO`,
@@ -286,7 +290,6 @@ pub(crate) fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> {
        //
        // SAFETY: `IS_ERR()` ensures `err` is a
        // negative value greater-or-equal to `-bindings::MAX_ERRNO`.
        #[allow(clippy::unnecessary_cast)]
        return Err(unsafe { Error::from_errno_unchecked(err as core::ffi::c_int) });
    }
    Ok(ptr)
Loading