Skip to content

Commit 5a9bc74

Browse files
authored
Merge pull request #80 from ryanbreen/fix/cow-frame-deallocation
fix(cow): prevent deallocation of untracked frames
2 parents 71cbb3e + 41c6845 commit 5a9bc74

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

kernel/src/memory/frame_metadata.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,20 @@ pub fn frame_decref(frame: PhysFrame) -> bool {
7676
// old_count > 1, still shared
7777
false
7878
} else {
79-
// Frame wasn't tracked - this is the sole owner
80-
// Return true to indicate it can be freed
81-
true
79+
// Frame wasn't tracked in CoW metadata.
80+
// This could be:
81+
// 1. A frame allocated by a child process after fork (could be freed)
82+
// 2. A frame that was never part of CoW sharing (might be unsafe to free)
83+
//
84+
// SAFETY: Don't free untracked frames. This causes a memory leak for
85+
// child-allocated pages, but prevents potential corruption if the frame
86+
// is still in use by something else. The root cause needs further
87+
// investigation.
88+
log::trace!(
89+
"frame_decref: frame {:#x} not tracked, refusing to free (leak to prevent corruption)",
90+
addr
91+
);
92+
false
8293
}
8394
}
8495

kernel/src/process/process.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,9 @@ impl Process {
291291
let frame = PhysFrame::containing_address(phys_addr);
292292

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

0 commit comments

Comments
 (0)