Skip to contentSkip to conversation

rust: task: use `as_char_ptr` instead of `as_ptr().cast()`

PATCH Applied Gary Guo 3 participants 4 messages Feb 3 – Mar 11 Rust

lore
Share & tools
lore

Gary Guo

author
#0 lore raw

PATCH v3 1/2 rust: task: use `as_char_ptr` instead of `as_ptr().cast()`

From: Gary Guo <[email protected]>

as_char_ptr would provide the correct (unsigned char) type without needing to convert to an intermediate type and cast the pointer.

The as_ptr() function is going to be disallowed by clippy warning, so fix this usage.

This is used only if CONFIG_DEBUG_ATOMIC_SLEEP=y. Instead of conditionally importing CStrExt, import it via prelude instead, and remove other imports that are already available via the prelude.

---
Changes since v2:
- Use CStrExt from prelude, as the use of it is conditional on CONFIG_DEBUG_ATOMIC_SLEEP
Link to v2: https://lore.kernel.org/rust-for-linux/[email protected]/#t

---
 rust/kernel/task.rs | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
rust/kernel/task.rs +3 -4
index cc907fb531bc..049c8a4d45d8 100644
@@ -6,16 +6,15 @@
 
 use crate::{
     bindings,
-    ffi::{c_int, c_long, c_uint},
     mm::MmWithUser,
     pid_namespace::PidNamespace,
+    prelude::*,
     sync::aref::ARef,
     types::{NotThreadSafe, Opaque},
 };
 use core::{
-    cmp::{Eq, PartialEq},
     ops::Deref,
-    ptr,
+    ptr, //
 };
 
 /// A sentinel value used for infinite timeouts.
@@ -419,7 +418,7 @@ pub fn might_sleep() {
         let file = kernel::file_from_location(loc);
 
         // SAFETY: `file.as_ptr()` is valid for reading and guaranteed to be nul-terminated.
-        unsafe { crate::bindings::__might_sleep(file.as_ptr().cast(), loc.line() as i32) }
+        unsafe { crate::bindings::__might_sleep(file.as_char_ptr(), loc.line() as i32) }
     }
 
     // SAFETY: Always safe to call.

base-commit: 4c87cdd0328495759f6e9f9f4e1e53ef8032a76f

Signature · 1 line
2.51.2
author
#1 lore raw

PATCH v3 2/2 rust: disallow use of `CStr::as_ptr` and `CStr::from_ptr`

From: Gary Guo <[email protected]>

As kernel always use unsigned char and not the platform ABI's default, an user should always use as_char_ptr provided via CStrExt instead. Therefore configure disallow-methods feature of clippy to catch incorrect usage.

Similarly, the dual from_ptr is also disallowed.

---
Changes since v2:
- Also disallow CStr::from_ptr

---
 .clippy.toml       | 10 ++++++++++
 rust/kernel/str.rs |  3 +++
 2 files changed, 13 insertions(+)
.clippy.toml +10 -0
index 137f41d203de..a51de9a46380 100644
@@ -9,3 +9,13 @@ disallowed-macros = [
     # it here, see: https://github.com/rust-lang/rust-clippy/issues/11303.
     { path = "kernel::dbg", reason = "the `dbg!` macro is intended as a debugging tool", allow-invalid = true },
 ]
+
+[[disallowed-methods]]
+path = "core::ffi::CStr::as_ptr"
+replacement = "kernel::prelude::CStrExt::as_char_ptr"
+reason = "kernel's `char` is always unsigned, use `as_char_ptr` instead"
+
+[[disallowed-methods]]
+path = "core::ffi::CStr::from_ptr"
+replacement = "kernel::prelude::CStrExt::from_char_ptr"
+reason = "kernel's `char` is always unsigned, use `from_char_ptr` instead"
rust/kernel/str.rs +3 -0
index fa87779d2253..97bf9427af59 100644
@@ -189,6 +189,7 @@ macro_rules! b_str {
 //
 // - error[E0379]: functions in trait impls cannot be declared const
 #[inline]
+#[expect(clippy::disallowed_methods, reason = "internal implementation")]
 pub const fn as_char_ptr_in_const_context(c_str: &CStr) -> *const c_char {
     c_str.as_ptr().cast()
 }
@@ -319,6 +320,7 @@ unsafe fn to_bytes_mut(s: &mut CStr) -> &mut [u8] {
 
 impl CStrExt for CStr {
     #[inline]
+    #[expect(clippy::disallowed_methods, reason = "internal implementation")]
     unsafe fn from_char_ptr<'a>(ptr: *const c_char) -> &'a Self {
         // SAFETY: The safety preconditions are the same as for `CStr::from_ptr`.
         unsafe { CStr::from_ptr(ptr.cast()) }
@@ -334,6 +336,7 @@ unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self {
     }
 
     #[inline]
+    #[expect(clippy::disallowed_methods, reason = "internal implementation")]
     fn as_char_ptr(&self) -> *const c_char {
         self.as_ptr().cast()
     }
Signature · 1 line
2.51.2
reviewer Reviewed-by on v3 2/2
#2 lore raw

Re: [PATCH v3 2/2] rust: disallow use of `CStr::as_ptr` and `CStr::from_ptr`

Quoted 11 lines · Gary Guo

From: Gary Guo <[email protected]>

As kernel always use unsigned char and not the platform ABI's default, an user should always use as_char_ptr provided via CStrExt instead. Therefore configure disallow-methods feature of clippy to catch incorrect usage.

Similarly, the dual from_ptr is also disallowed.

Quoted 57 lines

---
Changes since v2:
- Also disallow CStr::from_ptr

---
 .clippy.toml       | 10 ++++++++++
 rust/kernel/str.rs |  3 +++
 2 files changed, 13 insertions(+)
.clippy.toml +10 -0
index 137f41d203de..a51de9a46380 100644
@@ -9,3 +9,13 @@ disallowed-macros = [
     # it here, see: https://github.com/rust-lang/rust-clippy/issues/11303.
     { path = "kernel::dbg", reason = "the `dbg!` macro is intended as a debugging tool", allow-invalid = true },
 ]
+
+[[disallowed-methods]]
+path = "core::ffi::CStr::as_ptr"
+replacement = "kernel::prelude::CStrExt::as_char_ptr"
+reason = "kernel's `char` is always unsigned, use `as_char_ptr` instead"
+
+[[disallowed-methods]]
+path = "core::ffi::CStr::from_ptr"
+replacement = "kernel::prelude::CStrExt::from_char_ptr"
+reason = "kernel's `char` is always unsigned, use `from_char_ptr` instead"
rust/kernel/str.rs +3 -1
index fa87779d2253..97bf9427af59 100644
@@ -189,6 +189,7 @@ macro_rules! b_str {
 //
 // - error[E0379]: functions in trait impls cannot be declared const
 #[inline]
+#[expect(clippy::disallowed_methods, reason = "internal implementation")]
 pub const fn as_char_ptr_in_const_context(c_str: &CStr) -> *const c_char {
     c_str.as_ptr().cast()
 }
@@ -319,6 +320,7 @@ unsafe fn to_bytes_mut(s: &mut CStr) -> &mut [u8] {
 
 impl CStrExt for CStr {
     #[inline]
+    #[expect(clippy::disallowed_methods, reason = "internal implementation")]
     unsafe fn from_char_ptr<'a>(ptr: *const c_char) -> &'a Self {
         // SAFETY: The safety preconditions are the same as for `CStr::from_ptr`.
         unsafe { CStr::from_ptr(ptr.cast()) }
@@ -334,6 +336,7 @@ unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self {
     }
 
     #[inline]
+    #[expect(clippy::disallowed_methods, reason = "internal implementation")]
     fn as_char_ptr(&self) -> *const c_char {
         self.as_ptr().cast()
     }
--

2.51.2

Applied
#3 lore raw
In reply to Gary Guo
Quoted 9 lines · Gary Guo

From: Gary Guo <[email protected]>

as_char_ptr would provide the correct (unsigned char) type without needing to convert to an intermediate type and cast the pointer.

The as_ptr() function is going to be disallowed by clippy warning, so fix this usage.

Quoted 7 lines

This is used only if CONFIG_DEBUG_ATOMIC_SLEEP=y. Instead of conditionally importing CStrExt, import it via prelude instead, and remove other imports that are already available via the prelude.

Applied series to rust-next -- thanks everyone!

    [ As an example, without the previous commit, we would get a warning like:

          warning: use of a disallowed method `core::ffi::CStr::as_ptr`
             --> rust/kernel/task.rs:422:54
              |
          422 |         unsafe {
crate::bindings::__might_sleep(file.as_ptr().cast(), loc.line() as
i32) }
              |

^^^^^^ help: kernel's char is always unsigned, use as_char_ptr
instead: kernel::prelude::CStrExt::as_char_ptr
|
= help: for further information visit
https://rust-lang.github.io/rust-clippy/rust-1.94.0/index.html#disallowed_methods
= note: -W clippy::disallowed-methods implied by `-W
clippy::all`
= help: to override -W clippy::all add
#[allow(clippy::disallowed_methods)]

- Miguel ]

Cheers,
Miguel