* [PATCH] rust: configfs: skip unregister after failed registration
@ 2026-08-18 8:11 ` Younes Akhouayri via B4 Relay
2026-08-18 9:37 ` Andreas Hindborg
2026-08-18 10:49 ` Gary Guo
0 siblings, 2 replies; 7+ messages in thread
From: Younes Akhouayri via B4 Relay @ 2026-08-18 8:11 UTC (permalink / raw)
To: Andreas Hindborg, Breno Leitao, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan
Cc: rust-for-linux, linux-kernel, Younes Akhouayri
From: Younes Akhouayri <git@younes.io>
Subsystem::new() calls configfs_register_subsystem() from a fallible
pin_chain callback. If registration fails, ChainPinInit drops the
already initialized Subsystem. Its PinnedDrop currently calls
configfs_unregister_subsystem() unconditionally.
configfs_unregister_subsystem() requires registration to have completed
and immediately dereferences the subsystem dentry. Registering a
duplicate subsystem name returns -EEXIST before installing that dentry,
so the cleanup path dereferences NULL and panics the kernel.
Track successful registration explicitly and only unregister in that
state. Keep mutex destruction unconditional because it is initialized
before registration.
Fixes: 446cafc295bf ("rust: configfs: introduce rust support for configfs")
Signed-off-by: Younes Akhouayri <git@younes.io>
---
rust/kernel/configfs.rs | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
index cd082b83e9e7..f358e227ce09 100644
--- a/rust/kernel/configfs.rs
+++ b/rust/kernel/configfs.rs
@@ -130,6 +130,7 @@ pub struct Subsystem<Data> {
subsystem: Opaque<bindings::configfs_subsystem>,
#[pin]
data: Data,
+ registered: bool,
}
// SAFETY: We do not provide any operations on `Subsystem`.
@@ -173,12 +174,15 @@ pub fn new(
}
),
data <- data,
+ registered: false,
})
- .pin_chain(|this| {
+ .pin_chain(|mut this| {
crate::error::to_result(
// SAFETY: We initialized `this.subsystem` according to C API contract above.
unsafe { bindings::configfs_register_subsystem(this.subsystem.get()) },
- )
+ )?;
+ *this.as_mut().project().registered = true;
+ Ok(())
})
}
}
@@ -186,8 +190,10 @@ pub fn new(
#[pinned_drop]
impl<Data> PinnedDrop for Subsystem<Data> {
fn drop(self: Pin<&mut Self>) {
- // SAFETY: We registered `self.subsystem` in the initializer returned by `Self::new`.
- unsafe { bindings::configfs_unregister_subsystem(self.subsystem.get()) };
+ if self.registered {
+ // SAFETY: `registered` is only set after `self.subsystem` was registered.
+ unsafe { bindings::configfs_unregister_subsystem(self.subsystem.get()) };
+ }
// SAFETY: We initialized the mutex in `Subsystem::new`.
unsafe { bindings::mutex_destroy(&raw mut (*self.subsystem.get()).su_mutex) };
}
---
base-commit: 47f27155f17498fccb1f222f79089642337498a9
change-id: 20260817-fix-rust-configfs-registration-state-v1-fa33fcc69673
Best regards,
--
Younes Akhouayri <git@younes.io>
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] rust: configfs: skip unregister after failed registration
2026-08-18 8:11 ` [PATCH] rust: configfs: skip unregister after failed registration Younes Akhouayri via B4 Relay
@ 2026-08-18 9:37 ` Andreas Hindborg
2026-08-18 10:09 ` Andreas Hindborg
2026-08-18 10:49 ` Gary Guo
1 sibling, 1 reply; 7+ messages in thread
From: Andreas Hindborg @ 2026-08-18 9:37 UTC (permalink / raw)
To: Younes Akhouayri via B4 Relay, Breno Leitao, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Alice Ryhl, Trevor Gross, Danilo Krummrich, Daniel Almeida,
Tamir Duberstein, Alexandre Courbot, Onur Özkan
Cc: rust-for-linux, linux-kernel, Younes Akhouayri
"Younes Akhouayri via B4 Relay" <devnull+git.younes.io@kernel.org>
writes:
> From: Younes Akhouayri <git@younes.io>
>
> Subsystem::new() calls configfs_register_subsystem() from a fallible
> pin_chain callback. If registration fails, ChainPinInit drops the
> already initialized Subsystem. Its PinnedDrop currently calls
> configfs_unregister_subsystem() unconditionally.
>
> configfs_unregister_subsystem() requires registration to have completed
> and immediately dereferences the subsystem dentry. Registering a
> duplicate subsystem name returns -EEXIST before installing that dentry,
> so the cleanup path dereferences NULL and panics the kernel.
>
> Track successful registration explicitly and only unregister in that
> state. Keep mutex destruction unconditional because it is initialized
> before registration.
>
> Fixes: 446cafc295bf ("rust: configfs: introduce rust support for configfs")
> Signed-off-by: Younes Akhouayri <git@younes.io>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Looks good to me, will pick it in a few weeks.
Best regards,
Andreas Hindborg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] rust: configfs: skip unregister after failed registration
2026-08-18 9:37 ` Andreas Hindborg
@ 2026-08-18 10:09 ` Andreas Hindborg
0 siblings, 0 replies; 7+ messages in thread
From: Andreas Hindborg @ 2026-08-18 10:09 UTC (permalink / raw)
To: Younes Akhouayri via B4 Relay, Breno Leitao, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Alice Ryhl, Trevor Gross, Danilo Krummrich, Daniel Almeida,
Tamir Duberstein, Alexandre Courbot, Onur Özkan
Cc: rust-for-linux, linux-kernel, Younes Akhouayri
Andreas Hindborg <a.hindborg@kernel.org> writes:
> "Younes Akhouayri via B4 Relay" <devnull+git.younes.io@kernel.org>
> writes:
>
>> From: Younes Akhouayri <git@younes.io>
>>
>> Subsystem::new() calls configfs_register_subsystem() from a fallible
>> pin_chain callback. If registration fails, ChainPinInit drops the
>> already initialized Subsystem. Its PinnedDrop currently calls
>> configfs_unregister_subsystem() unconditionally.
>>
>> configfs_unregister_subsystem() requires registration to have completed
>> and immediately dereferences the subsystem dentry. Registering a
>> duplicate subsystem name returns -EEXIST before installing that dentry,
>> so the cleanup path dereferences NULL and panics the kernel.
>>
>> Track successful registration explicitly and only unregister in that
>> state. Keep mutex destruction unconditional because it is initialized
>> before registration.
>>
>> Fixes: 446cafc295bf ("rust: configfs: introduce rust support for configfs")
>> Signed-off-by: Younes Akhouayri <git@younes.io>
>
>
> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
>
> Looks good to me, will pick it in a few weeks.
Actually, we do not need the `as_mut` call:
diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
index fce994e7f8b8..62fd2d458a1c 100644
--- a/rust/kernel/configfs.rs
+++ b/rust/kernel/configfs.rs
@@ -176,12 +176,12 @@ pub fn new(
data <- data,
registered: false,
})
- .pin_chain(|mut this| {
+ .pin_chain(|this| {
crate::error::to_result(
// SAFETY: We initialized `this.subsystem` according to C API contract above.
unsafe { bindings::configfs_register_subsystem(this.subsystem.get()) },
)?;
- *this.as_mut().project().registered = true;
+ *this.project().registered = true;
Ok(())
})
}
Best regards,
Andreas Hindborg
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] rust: configfs: skip unregister after failed registration
2026-08-18 8:11 ` [PATCH] rust: configfs: skip unregister after failed registration Younes Akhouayri via B4 Relay
2026-08-18 9:37 ` Andreas Hindborg
@ 2026-08-18 10:49 ` Gary Guo
2026-08-18 10:53 ` Andreas Hindborg
1 sibling, 1 reply; 7+ messages in thread
From: Gary Guo @ 2026-08-18 10:49 UTC (permalink / raw)
To: git, Andreas Hindborg, Breno Leitao, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan
Cc: rust-for-linux, linux-kernel
On Tue Aug 18, 2026 at 9:11 AM BST, Younes Akhouayri via B4 Relay wrote:
> From: Younes Akhouayri <git@younes.io>
>
> Subsystem::new() calls configfs_register_subsystem() from a fallible
> pin_chain callback. If registration fails, ChainPinInit drops the
> already initialized Subsystem. Its PinnedDrop currently calls
> configfs_unregister_subsystem() unconditionally.
>
> configfs_unregister_subsystem() requires registration to have completed
> and immediately dereferences the subsystem dentry. Registering a
> duplicate subsystem name returns -EEXIST before installing that dentry,
> so the cleanup path dereferences NULL and panics the kernel.
>
> Track successful registration explicitly and only unregister in that
> state. Keep mutex destruction unconditional because it is initialized
> before registration.
>
> Fixes: 446cafc295bf ("rust: configfs: introduce rust support for configfs")
> Signed-off-by: Younes Akhouayri <git@younes.io>
> ---
> rust/kernel/configfs.rs | 14 ++++++++++----
> 1 file changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
> index cd082b83e9e7..f358e227ce09 100644
> --- a/rust/kernel/configfs.rs
> +++ b/rust/kernel/configfs.rs
> @@ -130,6 +130,7 @@ pub struct Subsystem<Data> {
> subsystem: Opaque<bindings::configfs_subsystem>,
> #[pin]
> data: Data,
> + registered: bool,
No flag just for destruction. Please change new logic to avoid needing this.
Best,
Gary
> }
>
> // SAFETY: We do not provide any operations on `Subsystem`.
> @@ -173,12 +174,15 @@ pub fn new(
> }
> ),
> data <- data,
> + registered: false,
> })
> - .pin_chain(|this| {
> + .pin_chain(|mut this| {
> crate::error::to_result(
> // SAFETY: We initialized `this.subsystem` according to C API contract above.
> unsafe { bindings::configfs_register_subsystem(this.subsystem.get()) },
> - )
> + )?;
> + *this.as_mut().project().registered = true;
> + Ok(())
> })
> }
> }
> @@ -186,8 +190,10 @@ pub fn new(
> #[pinned_drop]
> impl<Data> PinnedDrop for Subsystem<Data> {
> fn drop(self: Pin<&mut Self>) {
> - // SAFETY: We registered `self.subsystem` in the initializer returned by `Self::new`.
> - unsafe { bindings::configfs_unregister_subsystem(self.subsystem.get()) };
> + if self.registered {
> + // SAFETY: `registered` is only set after `self.subsystem` was registered.
> + unsafe { bindings::configfs_unregister_subsystem(self.subsystem.get()) };
> + }
> // SAFETY: We initialized the mutex in `Subsystem::new`.
> unsafe { bindings::mutex_destroy(&raw mut (*self.subsystem.get()).su_mutex) };
> }
>
> ---
> base-commit: 47f27155f17498fccb1f222f79089642337498a9
> change-id: 20260817-fix-rust-configfs-registration-state-v1-fa33fcc69673
>
> Best regards,
> --
> Younes Akhouayri <git@younes.io>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] rust: configfs: skip unregister after failed registration
2026-08-18 10:49 ` Gary Guo
@ 2026-08-18 10:53 ` Andreas Hindborg
2026-08-18 11:00 ` Gary Guo
0 siblings, 1 reply; 7+ messages in thread
From: Andreas Hindborg @ 2026-08-18 10:53 UTC (permalink / raw)
To: Gary Guo, git, Breno Leitao, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan
Cc: rust-for-linux, linux-kernel
"Gary Guo" <gary@garyguo.net> writes:
> On Tue Aug 18, 2026 at 9:11 AM BST, Younes Akhouayri via B4 Relay wrote:
>> From: Younes Akhouayri <git@younes.io>
>>
>> Subsystem::new() calls configfs_register_subsystem() from a fallible
>> pin_chain callback. If registration fails, ChainPinInit drops the
>> already initialized Subsystem. Its PinnedDrop currently calls
>> configfs_unregister_subsystem() unconditionally.
>>
>> configfs_unregister_subsystem() requires registration to have completed
>> and immediately dereferences the subsystem dentry. Registering a
>> duplicate subsystem name returns -EEXIST before installing that dentry,
>> so the cleanup path dereferences NULL and panics the kernel.
>>
>> Track successful registration explicitly and only unregister in that
>> state. Keep mutex destruction unconditional because it is initialized
>> before registration.
>>
>> Fixes: 446cafc295bf ("rust: configfs: introduce rust support for configfs")
>> Signed-off-by: Younes Akhouayri <git@younes.io>
>> ---
>> rust/kernel/configfs.rs | 14 ++++++++++----
>> 1 file changed, 10 insertions(+), 4 deletions(-)
>>
>> diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
>> index cd082b83e9e7..f358e227ce09 100644
>> --- a/rust/kernel/configfs.rs
>> +++ b/rust/kernel/configfs.rs
>> @@ -130,6 +130,7 @@ pub struct Subsystem<Data> {
>> subsystem: Opaque<bindings::configfs_subsystem>,
>> #[pin]
>> data: Data,
>> + registered: bool,
>
> No flag just for destruction. Please change new logic to avoid needing this.
I guess we can have a local `UnregisteredSubsystem` that we can
cast to a `Subsystem` once registration succeeds. Is that what you have
in mind?
Best regards,
Andreas Hindborg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] rust: configfs: skip unregister after failed registration
2026-08-18 10:53 ` Andreas Hindborg
@ 2026-08-18 11:00 ` Gary Guo
2026-08-18 12:24 ` Andreas Hindborg
0 siblings, 1 reply; 7+ messages in thread
From: Gary Guo @ 2026-08-18 11:00 UTC (permalink / raw)
To: Andreas Hindborg, Gary Guo, git, Breno Leitao, Miguel Ojeda,
Boqun Feng, Björn Roy Baron, Benno Lossin, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan
Cc: rust-for-linux, linux-kernel
On Tue Aug 18, 2026 at 11:53 AM BST, Andreas Hindborg wrote:
> "Gary Guo" <gary@garyguo.net> writes:
>
>> On Tue Aug 18, 2026 at 9:11 AM BST, Younes Akhouayri via B4 Relay wrote:
>>> From: Younes Akhouayri <git@younes.io>
>>>
>>> Subsystem::new() calls configfs_register_subsystem() from a fallible
>>> pin_chain callback. If registration fails, ChainPinInit drops the
>>> already initialized Subsystem. Its PinnedDrop currently calls
>>> configfs_unregister_subsystem() unconditionally.
>>>
>>> configfs_unregister_subsystem() requires registration to have completed
>>> and immediately dereferences the subsystem dentry. Registering a
>>> duplicate subsystem name returns -EEXIST before installing that dentry,
>>> so the cleanup path dereferences NULL and panics the kernel.
>>>
>>> Track successful registration explicitly and only unregister in that
>>> state. Keep mutex destruction unconditional because it is initialized
>>> before registration.
>>>
>>> Fixes: 446cafc295bf ("rust: configfs: introduce rust support for configfs")
>>> Signed-off-by: Younes Akhouayri <git@younes.io>
>>> ---
>>> rust/kernel/configfs.rs | 14 ++++++++++----
>>> 1 file changed, 10 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
>>> index cd082b83e9e7..f358e227ce09 100644
>>> --- a/rust/kernel/configfs.rs
>>> +++ b/rust/kernel/configfs.rs
>>> @@ -130,6 +130,7 @@ pub struct Subsystem<Data> {
>>> subsystem: Opaque<bindings::configfs_subsystem>,
>>> #[pin]
>>> data: Data,
>>> + registered: bool,
>>
>> No flag just for destruction. Please change new logic to avoid needing this.
>
> I guess we can have a local `UnregisteredSubsystem` that we can
> cast to a `Subsystem` once registration succeeds. Is that what you have
> in mind?
You can use the arbitrary code block feature of pin-init to run code before
arming the destructor:
_: {
let result = crate::error::to_result(
unsafe { bindings::configfs_register_subsystem(subsystem.get()) }
);
if let Err(err) = result {
unsafe { bindings::mutex_destroy(&raw mut (*subsystem.get()).su_mutex) };
}
result?
}
That said, why is the configfs not initializer the mutex, but rather users do?
Best,
Gary
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] rust: configfs: skip unregister after failed registration
2026-08-18 11:00 ` Gary Guo
@ 2026-08-18 12:24 ` Andreas Hindborg
0 siblings, 0 replies; 7+ messages in thread
From: Andreas Hindborg @ 2026-08-18 12:24 UTC (permalink / raw)
To: Gary Guo, Gary Guo, git, Breno Leitao, Miguel Ojeda, Boqun Feng,
Björn Roy Baron, Benno Lossin, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan
Cc: rust-for-linux, linux-kernel
"Gary Guo" <gary@garyguo.net> writes:
> On Tue Aug 18, 2026 at 11:53 AM BST, Andreas Hindborg wrote:
>> "Gary Guo" <gary@garyguo.net> writes:
>>
>>> On Tue Aug 18, 2026 at 9:11 AM BST, Younes Akhouayri via B4 Relay wrote:
>>>> From: Younes Akhouayri <git@younes.io>
>>>>
>>>> Subsystem::new() calls configfs_register_subsystem() from a fallible
>>>> pin_chain callback. If registration fails, ChainPinInit drops the
>>>> already initialized Subsystem. Its PinnedDrop currently calls
>>>> configfs_unregister_subsystem() unconditionally.
>>>>
>>>> configfs_unregister_subsystem() requires registration to have completed
>>>> and immediately dereferences the subsystem dentry. Registering a
>>>> duplicate subsystem name returns -EEXIST before installing that dentry,
>>>> so the cleanup path dereferences NULL and panics the kernel.
>>>>
>>>> Track successful registration explicitly and only unregister in that
>>>> state. Keep mutex destruction unconditional because it is initialized
>>>> before registration.
>>>>
>>>> Fixes: 446cafc295bf ("rust: configfs: introduce rust support for configfs")
>>>> Signed-off-by: Younes Akhouayri <git@younes.io>
>>>> ---
>>>> rust/kernel/configfs.rs | 14 ++++++++++----
>>>> 1 file changed, 10 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
>>>> index cd082b83e9e7..f358e227ce09 100644
>>>> --- a/rust/kernel/configfs.rs
>>>> +++ b/rust/kernel/configfs.rs
>>>> @@ -130,6 +130,7 @@ pub struct Subsystem<Data> {
>>>> subsystem: Opaque<bindings::configfs_subsystem>,
>>>> #[pin]
>>>> data: Data,
>>>> + registered: bool,
>>>
>>> No flag just for destruction. Please change new logic to avoid needing this.
>>
>> I guess we can have a local `UnregisteredSubsystem` that we can
>> cast to a `Subsystem` once registration succeeds. Is that what you have
>> in mind?
>
> You can use the arbitrary code block feature of pin-init to run code before
> arming the destructor:
>
> _: {
> let result = crate::error::to_result(
> unsafe { bindings::configfs_register_subsystem(subsystem.get()) }
> );
> if let Err(err) = result {
> unsafe { bindings::mutex_destroy(&raw mut (*subsystem.get()).su_mutex) };
> }
> result?
> }
Neat, I did not know about that.
>
> That said, why is the configfs not initializer the mutex, but rather users do?
That is just the way configfs expects users to use the API. C users can
initialize statically as well by assigning the mutex at declaration
time. Try to grep for `init.*su_mutex` at kernel root.
Best regards,
Andreas Hindborg
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-18 12:25 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <8L_eiohtkr-KVK8wOx5hbz_bo8XmfV8FHHX0zNjlG9RROwHwX_qm_KwmORgQkKq0k06TyMCArt_3HoW5QoGM4A==@protonmail.internalid>
2026-08-18 8:11 ` [PATCH] rust: configfs: skip unregister after failed registration Younes Akhouayri via B4 Relay
2026-08-18 9:37 ` Andreas Hindborg
2026-08-18 10:09 ` Andreas Hindborg
2026-08-18 10:49 ` Gary Guo
2026-08-18 10:53 ` Andreas Hindborg
2026-08-18 11:00 ` Gary Guo
2026-08-18 12:24 ` Andreas Hindborg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).