From 9b68d4de80bd731fb64308e439cc44a6151ae930 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 23 Jun 2024 00:35:58 +0200 Subject: [PATCH] Fix add_ref(Shared) refcounting bug. --- src/context/memory.rs | 6 ++++++ src/memory/mod.rs | 2 +- syscall | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/context/memory.rs b/src/context/memory.rs index 7dc985b433..e3bb7dd34c 100644 --- a/src/context/memory.rs +++ b/src/context/memory.rs @@ -1602,6 +1602,12 @@ impl Grant { } // Cannot be shared and CoW simultaneously. Err(AddRefError::SharedToCow) => { + // The call to cow() later implicitly removes one ref, so add it here + // first, even if Shared. + if src_page_info.add_ref(RefKind::Shared) == Err(AddRefError::RcOverflow) { + return Err(Enomem); + } + // TODO: Copy in place, or use a zeroed page? let CowResult { new_frame, old_frame } = cow(src_frame, src_page_info, rk).map_err(|_| Enomem)?; if let Some(old_frame) = old_frame { diff --git a/src/memory/mod.rs b/src/memory/mod.rs index b791e50f24..145aa40cf4 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -643,7 +643,7 @@ pub fn init_mm(allocator: BumpAllocator) { THE_ZEROED_FRAME.get().write(Some((the_frame, the_info))); } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum AddRefError { CowToShared, SharedToCow, diff --git a/syscall b/syscall index 5b07568677..1583e94276 160000 --- a/syscall +++ b/syscall @@ -1 +1 @@ -Subproject commit 5b075686774ef88374d93834c54e339d456a8ec2 +Subproject commit 1583e94276dbd84f4e23f044accadef5bb28ad6b