Skip to content
Merged
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
10 changes: 8 additions & 2 deletions eclipse_kernel/src/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2501,9 +2501,14 @@ impl Scheme for FileSystemScheme {
if offset >= file_size {
return Err(scheme_error::EINVAL);
}
// `want` is how many bytes actually exist in the file for this mapping.
// `len` may be larger (memsz > filesz) when the segment has a BSS extension.
// We must allocate pages for the full `len` so that the BSS region is backed
// by zeroed physical memory rather than whatever happened to follow the
// file-data allocation in the physical frame pool.
let max_len = file_size - offset;
let want = core::cmp::min(len, max_len);
let aligned_len = (want + 0xFFF) & !0xFFF;
let aligned_len = (len + 0xFFF) & !0xFFF;
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aligned_len is computed with (len + 0xFFF) & !0xFFF, which can overflow/wrap for very large len values (release builds wrap). Since len ultimately comes from userspace mmap, this can lead to allocating/zeroing the wrong amount of memory. Use a checked/saturating align-up (e.g., len.checked_add(0xFFF) + mask) and return EINVAL on overflow.

Suggested change
let aligned_len = (len + 0xFFF) & !0xFFF;
let Some(aligned_len) = len.checked_add(0xFFF).map(|v| v & !0xFFF) else {
return Err(scheme_error::EINVAL);
};

Copilot uses AI. Check for mistakes.
if aligned_len == 0 {
return Err(scheme_error::EINVAL);
}
Expand All @@ -2518,7 +2523,8 @@ impl Scheme for FileSystemScheme {
crate::memory::frame_info::set_refcount(start_phys + i * 4096, 1);
}

// Zero the whole region and read file bytes into it.
// Zero the whole region (covers both file data and BSS extension), then
// copy only the file portion (`want` bytes) into the start of the buffer.
let kptr = (crate::memory::PHYS_MEM_OFFSET + start_phys) as *mut u8;
unsafe { core::ptr::write_bytes(kptr, 0, aligned_len); }
let dst = unsafe { core::slice::from_raw_parts_mut(kptr, want) };
Expand Down
Loading