3 ms·
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 fun
by aw1621107 10mo ago
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-2025-68260-558d@gregkh/ https://lore.kernel.org/linux-cve-announce/2025121614-CVE-20...
[1]: https://github.com/torvalds/linux/commit/3e0ae02ba831da2b707905f4e602e43f8507b8cc https://github.com/torvalds/linux/commit/3e0ae02ba831da2b707...
[2]: https://github.com/torvalds/linux/blob/3e0ae02ba831da2b707905f4e602e43f8507b8cc/drivers/android/binder/node.rs#L536 https://github.com/torvalds/linux/blob/3e0ae02ba831da2b70790...
[3]: https://github.com/torvalds/linux/blob/3e0ae02ba831da2b707905f4e602e43f8507b8cc/drivers/android/binder/node.rs#L993 https://github.com/torvalds/linux/blob/3e0ae02ba831da2b70790...
- anon-3988 10mo agoThe 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?
- aw1621107 10mo agoThe `unsafe` block was present because `List::remove` is marked `unsafe` [0]: /// Removes the provided item from this list and returns it. /// /// This returns `None` if the item is not in the list. (Note that by the safety requirements, /// this means that the item is not in any list.) /// /// # Safety /// /// `item` must not be in a different linked list (with the same id). pub unsafe fn remove(&mut self, item: &T) -> Option<ListArc<T, ID>> { I think it'd be tricky at best to make this particular API safe since doing so requires reasoning across arbitrary other List instances. At the very least I don't think locks would help here, since temporary exclusive access to a list won't stop you from adding the same element to multiple lists. [0]: https://github.com/torvalds/linux/blob/3e0ae02ba831da2b707905f4e602e43f8507b8cc/rust/kernel/list.rs#L582 https://github.com/torvalds/linux/blob/3e0ae02ba831da2b70790...
- mlindner 10mo agoIf the API cannot be made safe then it must be marked unsafe.
- deleted 10mo ago[deleted]
- aw1621107 10mo agoI mean, remove() is already marked unsafe? Otherwise there's the question of where exactly the API boundaries are. In the most general case, your unsafe boundary is going to be the module boundary; as long as what you publicly expose is safe modulo bugs, you're good. In this case the fix was in a crate-internal function, so I suppose one could argue that the public API was/is fine. That being said, I'm not super-familiar with the code in question so I can't definitively say that there's no way to make internal changes to reduce the risk of similar errors.
- mlindner 10mo agoYeah this is a bad fix. It should be impossible to cause incorrect things to happen from safe code, especially from safe code calling safe code.