Fix BSS segment corruption in file-backed mmap (dynamic library loading)#331
Conversation
Agent-Logs-Url: https://github.com/Pryancito/eclipse/sessions/6fc1a83f-eccd-4ebf-88cf-cd3e9be86467 Co-authored-by: Pryancito <4010159+Pryancito@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes incorrect physical backing for file-backed mmap when the requested mapping length (len) exceeds the file-data portion (filesz, i.e., memsz > filesz BSS extension). This prevents BSS pages from mapping to unrelated/unallocated physical frames containing stale data, which can crash dynamic library initialization.
Changes:
- In
FileSystemScheme::fmapforOpenFile::Real, computealigned_lenfrom the full requestedlen(not fromwant). - Clarify comments around
want(file bytes) vslen(file bytes + BSS extension) and the zeroing/copy behavior.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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; |
There was a problem hiding this comment.
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.
| let aligned_len = (len + 0xFFF) & !0xFFF; | |
| let Some(aligned_len) = len.checked_add(0xFFF).map(|v| v & !0xFFF) else { | |
| return Err(scheme_error::EINVAL); | |
| }; |
When
fmaphandles a file-backed mapping wherememsz > filesz(BSS extension), it was allocating physical pages based onmin(len, file_size - offset)— the file-data portion only — whilesys_mmapmappedlen-worth of pages using that physical address. BSS pages fell outside the allocation, mapping to adjacent unallocated physical frames with stale content. BSS globals initialized to zero by the ABI held garbage values, causing null-pointer-ish dereferences during shared library init.Observed crash: lightdm (dynamic binary) faulted at
CR2=0x7ce8withRAX=0x7cd8— a GLib/GObject BSS global used as a pointer, non-zero due to this bug.Changes
filesystem.rs—fmapforOpenFile::Real: computealigned_lenfrom the full requestedlenrather thanwant. The pre-existingwrite_bytes(..., 0, aligned_len)already zeros the whole region; only the file-data slice (wantbytes) is read from disk — no change to the read path.