A process can retain a valid mmap() address range after another operation shrinks the backing file, then receive SIGBUS when it touches a mapped page past the file’s new end. The mapping itself has not vanished. Its backing object no longer covers every page that the virtual mapping originally referenced.
This boundary is easy to miss because mapping lifetime and file size are separate state. Closing the original file descriptor does not invalidate an established mapping, and shrinking the file does not act like munmap() on every process that maps it.
The virtual mapping can outlive backing storage
For a regular file mapping, mmap() establishes virtual addresses associated with offsets in the file. The requested mapping length describes an address-space range; it does not freeze the file at its current size.
Suppose a process maps 16 KiB from a file that is 16 KiB long. A second process then truncates that file to 4 KiB. The first process can still have a 16 KiB virtual mapping recorded in its address space. Accesses do not all have the same outcome, however.
Addresses corresponding to the retained part of the file can remain usable. Whole mapped pages beyond the new end no longer have file storage behind them. On Linux, touching such a page can deliver SIGBUS.
This differs from accessing an unmapped address. munmap() removes a mapping, and a later reference to that address is an invalid virtual-memory access commonly reported as SIGSEGV. Truncation leaves a different condition: a mapping exists, but the mapped object cannot satisfy the referenced file offset.
File size is checked at access time
Memory-mapped I/O makes ordinary loads and stores depend on backing-object state that can change independently. A page may already be resident, or a later access may require the kernel to resolve a page fault. File truncation changes which offsets remain valid in the object.
POSIX specifies that when ftruncate() decreases the size of a mapped file, whole pages beyond the new end are discarded. References to those discarded pages generate SIGBUS. Linux documents the same signal for access to a mapped page beyond the end of the mapped file.
The result is a concurrency boundary between virtual-memory users and file-size mutation. A pointer being inside the original mmap() length is not sufficient evidence that its backing file offset still exists.
The final partial page is a distinct case
The end of a file does not normally align with the system page size. That creates a separate boundary from whole pages beyond end-of-file.
For a file whose last byte falls partway through a page, Linux zero-fills the remaining bytes of that page when mapped. Modifications to bytes beyond the file end in that final partial page are not written back to the file. Whole pages after the object end are the region associated with SIGBUS on access.
This distinction matters when a truncation target is not page-aligned. A mapping can contain a final page that partly corresponds to the file and partly lies beyond its logical size. Code that treats every byte up to the page boundary as durable file content can silently rely on bytes that have no file representation.
Atomic replacement avoids mutating an active inode
A common production form of this failure appears when one process maps a data file while another refreshes that file in place. Rewriting through the same inode can expose size transitions to existing mappings. A truncate-then-write sequence is especially hazardous because mapped readers can observe the shortened object before replacement data has been written.
Replacing a pathname with a newly written file has different mapping semantics. Existing mappings continue to reference the old file object, while later opens through the pathname can reach the replacement. The pathname update does not retarget established mappings to the new inode.
That property makes file replacement materially different from in-place truncation for mapped readers. It does not by itself provide every durability or coordination guarantee, but it avoids shrinking the object beneath mappings that already reference it.
Signal handling is not a general recovery boundary
Catching SIGBUS does not turn arbitrary mapped access into a safe retry mechanism. The fault can arise from normal application loads generated by compiled code, and resuming execution requires a valid strategy for the faulting instruction and the mapping state. Concurrent file mutation can also continue after the handler runs.
Systems that permit mapped readers alongside file replacement usually place the consistency boundary outside individual memory accesses. Immutable file generations, descriptor-based handoff, versioned paths, or explicit coordination keep a mapped object’s size stable for the period in which readers may dereference it.
The central constraint is object stability rather than pointer validity. A mapped address can remain present in a process while the file range behind that address has ceased to exist.