Commit 91ae26b0 authored by Danilo Krummrich's avatar Danilo Krummrich
Browse files

rust: devres: initialize Devres::inner::data last

Users may want to access the Devres object from callbacks registered
through the initialization of Devres::inner::data.

For those accesses to be valid, Devres::inner::data must be initialized
last [1].

Credit to Boqun for spotting this [2].

Link: https://lore.kernel.org/lkml/DBBPHO26CPBS.2OVI1OERCB2J5@kernel.org/ [1]
Link: https://lore.kernel.org/lkml/aHSmxWeIy3L-AKIV@Mac.home/

 [2]
Reviewed-by: default avatarAlice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20250714113712.22158-1-dakr@kernel.org


Signed-off-by: default avatarDanilo Krummrich <dakr@kernel.org>
parent 3964d07d
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -137,14 +137,10 @@ pub fn new<'a, E>(
        let callback = Self::devres_callback;

        try_pin_init!(&this in Self {
            // INVARIANT: `inner` is properly initialized.
            inner <- Opaque::pin_init(try_pin_init!(Inner {
                data <- Revocable::new(data),
                devm <- Completion::new(),
                revoke <- Completion::new(),
            })),
            dev: dev.into(),
            callback,
            dev: {
            // INVARIANT: `inner` is properly initialized.
            inner <- {
                // SAFETY: `this` is a valid pointer to uninitialized memory.
                let inner = unsafe { &raw mut (*this.as_ptr()).inner };

@@ -158,7 +154,11 @@ pub fn new<'a, E>(
                    bindings::devm_add_action(dev.as_raw(), Some(callback), inner.cast())
                })?;

                dev.into()
                Opaque::pin_init(try_pin_init!(Inner {
                    devm <- Completion::new(),
                    revoke <- Completion::new(),
                    data <- Revocable::new(data),
                }))
            },
        })
    }