logoalt Hacker News

aw1621107today at 6:44 PM1 replyview on HN

Direct link to the mailing list entry at [0]. The fix for 6.19-rc1 is commit 3e0ae02ba831 [1]. The patch is pretty small (added some extra context since the function it's from is short):

        pub(crate) fn release(&self) {
            let mut guard = self.owner.inner.lock();
            while let Some(work) = self.inner.access_mut(&mut guard).oneway_todo.pop_front() {
                drop(guard);
                work.into_arc().cancel();
                guard = self.owner.inner.lock();
            }

    -       let death_list = core::mem::take(&mut self.inner.access_mut(&mut guard).death_list);
    -       drop(guard);
    -       for death in death_list {
    +       while let Some(death) = self.inner.access_mut(&mut guard).death_list.pop_front() {
    +           drop(guard);
                death.into_arc().set_dead();
    +           guard = self.owner.inner.lock();
            }
        }
And here is the unsafe block mentioned in the commit message with some more context [3]:

    fn set_cleared(self: &DArc<Self>, abort: bool) -> bool {
        // <snip>

        // Remove death notification from node.
        if needs_removal {
            let mut owner_inner = self.node.owner.inner.lock();
            let node_inner = self.node.inner.access_mut(&mut owner_inner);
            // SAFETY: A `NodeDeath` is never inserted into the death list of any node other than
            // its owner, so it is either in this death list or in no death list.
            unsafe { node_inner.death_list.remove(self) };
        }
        needs_queueing
    }
[0]: https://lore.kernel.org/linux-cve-announce/2025121614-CVE-20...

[1]: https://github.com/torvalds/linux/commit/3e0ae02ba831da2b707...

[2]: https://github.com/torvalds/linux/blob/3e0ae02ba831da2b70790...

[3]: https://github.com/torvalds/linux/blob/3e0ae02ba831da2b70790...


Replies

anon-3988today at 7:16 PM

The interesting part to me is that this bug does not necessarily happen in an unsafe block. The fix happens in an unsafe block, I think the API should change to avoid this. Perhaps by forcing users to pass a lambda to do stuff instead of having to manually lock and drop?

show 2 replies