Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions kernel/src/memory/frame_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,20 @@ pub fn frame_decref(frame: PhysFrame) -> bool {
// old_count > 1, still shared
false
} else {
// Frame wasn't tracked - this is the sole owner
// Return true to indicate it can be freed
true
// Frame wasn't tracked in CoW metadata.
// This could be:
// 1. A frame allocated by a child process after fork (could be freed)
// 2. A frame that was never part of CoW sharing (might be unsafe to free)
//
// SAFETY: Don't free untracked frames. This causes a memory leak for
// child-allocated pages, but prevents potential corruption if the frame
// is still in use by something else. The root cause needs further
// investigation.
log::trace!(
"frame_decref: frame {:#x} not tracked, refusing to free (leak to prevent corruption)",
addr
);
false
}
}

Expand Down
4 changes: 3 additions & 1 deletion kernel/src/process/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,9 @@ impl Process {
let frame = PhysFrame::containing_address(phys_addr);

// Decrement reference count
// If this was the last reference, deallocate the frame
// If this was the last reference (frame was tracked and refcount reached 0),
// deallocate the frame. frame_decref returns false for untracked frames
// to prevent corruption from freeing potentially in-use frames.
if frame_decref(frame) {
deallocate_frame(frame);
freed_count += 1;
Expand Down
Loading