Skip to contentSkip to conversation

rust: disallow use of `CStr::as_ptr`

PATCH In review Gary Guo 6 participants 12 messages Jan 21 – Jan 22 Rust

lore
Share & tools
lore

Gary Guo

author
#0 lore raw

PATCH 1/1 rust: disallow use of `CStr::as_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.

---
 .clippy.toml       | 5 +++++
 rust/kernel/str.rs | 2 ++
 2 files changed, 7 insertions(+)
.clippy.toml +5 -0
index 137f41d203de..fd934bc04242 100644
@@ -9,3 +9,8 @@ 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."
rust/kernel/str.rs +2 -0
index fa87779d2253..08b8e2ebc8ad 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()
 }
@@ -334,6 +335,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
#1 lore raw
Quoted 2 lines · Gary Guo

+#[expect(clippy::disallowed_methods, reason = "internal implementation")]

Should we hide them too?

Cheers,
Miguel

reviewer
#2 lore raw
Quoted 5 lines · Miguel Ojeda
Quoted 2 lines · Gary Guo

+#[expect(clippy::disallowed_methods, reason = "internal implementation")]

Should we hide them too?

These are the methods that we want people to use? The "internal implementation" means that the use of CStr::as_char() is the internal implementation detail of as_char_ptr so it's okay. But nobody else should use it.

Best,
Gary

Quoted 3 lines

Cheers,
Miguel

#3 lore raw
Quoted 4 lines · Gary Guo

These are the methods that we want people to use? The "internal implementation" means that the use of CStr::as_char() is the internal implementation detail of as_char_ptr so it's okay. But nobody else should use it.

Yeah, not sure how I read that, sorry. And obviously we can't (easily) add it to core one.

Cheers,
Miguel

reviewer Acked-by on v1 1/1
#4 lore raw
In reply to Gary Guo
Quoted 19 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.

---
 .clippy.toml       | 5 +++++
 rust/kernel/str.rs | 2 ++
 2 files changed, 7 insertions(+)
.clippy.toml +0 -0
index 137f41d203de..fd934bc04242 100644

.clippy.toml disallowed-macros = [ · line 16

Quoted 8 lines
.clippy.toml +5 -0
@@ -9,3 +9,8 @@ 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."

In the disallowed-macros section above we seem to use sentence fragments (no capitalization, no trailing period).

Quoted 13 lines
rust/kernel/str.rs +1 -0
index fa87779d2253..08b8e2ebc8ad 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()
 }

rust/kernel/str.rs unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self { · line 338

Quoted 4 lines
rust/kernel/str.rs +1 -0
@@ -334,6 +335,7 @@ unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self {
     }
 
     #[inline]
+    #[expect(clippy::disallowed_methods, reason = "internal implementation")]

Can this be inside the function, on the as_ptr call itself?

Quoted 7 lines
rust/kernel/str.rs +0 -1
     fn as_char_ptr(&self) -> *const c_char {
         self.as_ptr().cast()
     }
 
--

2.51.2

reviewer
#5 lore raw
Quoted 15 lines · Tamir Duberstein
Quoted 14 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.

---
 .clippy.toml       | 5 +++++
 rust/kernel/str.rs | 2 ++
 2 files changed, 7 insertions(+)
Quoted 16 lines

.clippy.toml disallowed-macros = [ · line 16

Quoted 13 lines
.clippy.toml +5 -0
index 137f41d203de..fd934bc04242 100644
@@ -9,3 +9,8 @@ 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."

In the disallowed-macros section above we seem to use sentence fragments (no capitalization, no trailing period).

Ok.

Quoted 16 lines
Quoted 16 lines
rust/kernel/str.rs +1 -0
index fa87779d2253..08b8e2ebc8ad 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()
 }
@@ -334,6 +335,7 @@ unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self {
     }
 
Quoted 4 lines

rust/kernel/str.rs unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self { · line 338

Quoted 2 lines
rust/kernel/str.rs +1 -0
     #[inline]
+    #[expect(clippy::disallowed_methods, reason = "internal implementation")]

Can this be inside the function, on the as_ptr call itself?

You cannot apply attributes on expressions (yet). If this is to be moved into the function, there needs an additional block, which I think is just unnecessary.

Best,
Gary

Quoted 10 lines
Quoted 8 lines
rust/kernel/str.rs +0 -1
     fn as_char_ptr(&self) -> *const c_char {
         self.as_ptr().cast()
     }
 
--

2.51.2

#6 lore raw
Quoted 52 lines · Gary Guo
Quoted 15 lines · Tamir Duberstein
Quoted 14 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.

---
 .clippy.toml       | 5 +++++
 rust/kernel/str.rs | 2 ++
 2 files changed, 7 insertions(+)
Quoted 16 lines

.clippy.toml disallowed-macros = [ · line 16

Quoted 13 lines
.clippy.toml +5 -0
index 137f41d203de..fd934bc04242 100644
@@ -9,3 +9,8 @@ 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."

In the disallowed-macros section above we seem to use sentence fragments (no capitalization, no trailing period).

Ok.

Quoted 16 lines
Quoted 16 lines
rust/kernel/str.rs +1 -0
index fa87779d2253..08b8e2ebc8ad 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()
 }
@@ -334,6 +335,7 @@ unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self {
     }
 
Quoted 8 lines
Quoted 4 lines

rust/kernel/str.rs unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self { · line 338

Quoted 2 lines
rust/kernel/str.rs +1 -0
     #[inline]
+    #[expect(clippy::disallowed_methods, reason = "internal implementation")]

Can this be inside the function, on the as_ptr call itself?

You cannot apply attributes on expressions (yet). If this is to be moved into the function, there needs an additional block, which I think is just unnecessary.

Thought so. Should we add a TODO that links to the relevant upstream issue, or track it in
https://github.com/Rust-for-Linux/linux/issues/2?

Quoted 16 lines

Best,
Gary

Quoted 10 lines
Quoted 8 lines
rust/kernel/str.rs +0 -1
     fn as_char_ptr(&self) -> *const c_char {
         self.as_ptr().cast()
     }
 
--

2.51.2

reviewer
#7 lore raw
Quoted 58 lines · Tamir Duberstein
Quoted 57 lines · Gary Guo
Quoted 15 lines · Tamir Duberstein
Quoted 14 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.

---
 .clippy.toml       | 5 +++++
 rust/kernel/str.rs | 2 ++
 2 files changed, 7 insertions(+)
Quoted 16 lines

.clippy.toml disallowed-macros = [ · line 16

Quoted 13 lines
.clippy.toml +5 -0
index 137f41d203de..fd934bc04242 100644
@@ -9,3 +9,8 @@ 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."

In the disallowed-macros section above we seem to use sentence fragments (no capitalization, no trailing period).

Ok.

Quoted 20 lines
Quoted 14 lines
rust/kernel/str.rs +1 -0
index fa87779d2253..08b8e2ebc8ad 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()
 }

rust/kernel/str.rs unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self { · line 338

Quoted 4 lines
rust/kernel/str.rs +1 -0
@@ -334,6 +335,7 @@ unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self {
     }
 
     #[inline]
+    #[expect(clippy::disallowed_methods, reason = "internal implementation")]

Can this be inside the function, on the as_ptr call itself?

Quoted 7 lines
Quoted 3 lines

You cannot apply attributes on expressions (yet). If this is to be moved into the function, there needs an additional block, which I think is just unnecessary.

Thought so. Should we add a TODO that links to the relevant upstream issue, or track it in
https://github.com/Rust-for-Linux/linux/issues/2?

I don't think we really this need this.

If Miguel thinks this is useful then he can add it to the tracking issue.

Best,
Gary

Quoted 13 lines
Quoted 13 lines
Quoted 11 lines
Quoted 9 lines
rust/kernel/str.rs +0 -1
     fn as_char_ptr(&self) -> *const c_char {
         self.as_ptr().cast()
     }
 
--

2.51.2

#8 lore raw
Quoted 64 lines · Gary Guo
Quoted 62 lines · Tamir Duberstein
Quoted 60 lines · Gary Guo
Quoted 15 lines · Tamir Duberstein
Quoted 14 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.

---
 .clippy.toml       | 5 +++++
 rust/kernel/str.rs | 2 ++
 2 files changed, 7 insertions(+)
Quoted 16 lines

.clippy.toml disallowed-macros = [ · line 16

Quoted 13 lines
.clippy.toml +5 -0
index 137f41d203de..fd934bc04242 100644
@@ -9,3 +9,8 @@ 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."

In the disallowed-macros section above we seem to use sentence fragments (no capitalization, no trailing period).

Ok.

Quoted 16 lines
Quoted 16 lines
rust/kernel/str.rs +1 -0
index fa87779d2253..08b8e2ebc8ad 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()
 }
@@ -334,6 +335,7 @@ unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self {
     }
 
Quoted 4 lines

rust/kernel/str.rs unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self { · line 338

Quoted 2 lines
rust/kernel/str.rs +1 -0
     #[inline]
+    #[expect(clippy::disallowed_methods, reason = "internal implementation")]

Can this be inside the function, on the as_ptr call itself?

You cannot apply attributes on expressions (yet). If this is to be moved into the function, there needs an additional block, which I think is just unnecessary.

Quoted 7 lines
Quoted 3 lines

Thought so. Should we add a TODO that links to the relevant upstream issue, or track it in
https://github.com/Rust-for-Linux/linux/issues/2?

I don't think we really this need this.

If Miguel thinks this is useful then he can add it to the tracking issue.

Well, what is "it"? Do you know the upstream issue?

Quoted 18 lines

Best,
Gary

Quoted 13 lines
Quoted 13 lines
Quoted 11 lines
Quoted 9 lines
rust/kernel/str.rs +0 -1
     fn as_char_ptr(&self) -> *const c_char {
         self.as_ptr().cast()
     }
 
--

2.51.2

#11 lore raw
In reply to Gary Guo
kernel test robot noticed the following build warnings:

Hi Gary,

kernel test robot noticed the following build warnings:

[auto build test WARNING on rust/rust-next]
[also build test WARNING on next-20260121]
[cannot apply to linus/master v6.16-rc1]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Gary-Guo/rust-disallow-use-of-CStr-as_ptr/20260122-014335
base:   https://github.com/Rust-for-Linux/linux rust-next
patch link:    https://lore.kernel.org/r/20260121165835.4097975-1-gary%40kernel.org
patch subject: [PATCH] rust: disallow use of `CStr::as_ptr`
config: x86_64-rhel-9.4-rust (https://download.01.org/0day-ci/archive/20260122/[email protected]/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
rustc: rustc 1.88.0 (6b00bc388 2025-06-23)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

>> 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/master/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)]

Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki