Skip to content

Commit a49a173

Browse files
alindimajiangliu
authored andcommitted
MmapRegion: relax mmap size constraints
For the build_raw() alternative of the MmapRegion, the implementation was validating that the length of the mapping was a multiple of the page size. This generally makes sense, since the OS will round up to the nearest multiple anyway and only allocate full pages. There is one corner case though where this needs to be relaxed: when mapping a file with a length not divisible by the pagesize. According to the POSIX reference, the length will be rounded up and the extra memory zero-ed. Memory accesses will work as expected, even beyond the actual file length (but within the allocated memory), but any writes will not be persisted to the filesystem and the backing device. This is a use case where mapping an "uneven" length makes sense, so that such "out-of-bounds" checks can be caught by accesses via vm-memory primitives. This commit removes this constraint. Signed-off-by: alindima <[email protected]>
1 parent 0343e0a commit a49a173

File tree

1 file changed

+1
-15
lines changed

1 file changed

+1
-15
lines changed

src/mmap_unix.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ pub enum Error {
2929
InvalidOffsetLength,
3030
/// The specified pointer to the mapping is not page-aligned.
3131
InvalidPointer,
32-
/// The specified size for the region is not a multiple of the page size.
33-
InvalidSize,
3432
/// The forbidden `MAP_FIXED` flag was specified.
3533
MapFixed,
3634
/// Mappings using the same fd overlap in terms of file offset and length.
@@ -52,10 +50,6 @@ impl fmt::Display for Error {
5250
f,
5351
"The specified pointer to the mapping is not page-aligned",
5452
),
55-
Error::InvalidSize => write!(
56-
f,
57-
"The specified size for the region is not a multiple of the page size",
58-
),
5953
Error::MapFixed => write!(f, "The forbidden `MAP_FIXED` flag was specified"),
6054
Error::MappingOverlap => write!(
6155
f,
@@ -204,11 +198,6 @@ impl<B: Bitmap> MmapRegionBuilder<B> {
204198
return Err(Error::InvalidPointer);
205199
}
206200

207-
// Check that the size is a multiple of the page size.
208-
if self.size & (page_size - 1) != 0 {
209-
return Err(Error::InvalidSize);
210-
}
211-
212201
Ok(MmapRegion {
213202
addr,
214203
size: self.size,
@@ -309,7 +298,7 @@ impl<B: NewBitmap> MmapRegion<B> {
309298
///
310299
/// # Arguments
311300
/// * `addr` - Pointer to the start of the mapping. Must be page-aligned.
312-
/// * `size` - The size of the memory region in bytes. Must be a multiple of the page size.
301+
/// * `size` - The size of the memory region in bytes.
313302
/// * `prot` - Must correspond to the memory protection attributes of the existing mapping.
314303
/// * `flags` - Must correspond to the flags that were passed to `mmap` for the creation of
315304
/// the existing mapping.
@@ -636,9 +625,6 @@ mod tests {
636625
let r = unsafe { MmapRegion::build_raw((addr + 1) as *mut u8, size, prot, flags) };
637626
assert_eq!(format!("{:?}", r.unwrap_err()), "InvalidPointer");
638627

639-
let r = unsafe { MmapRegion::build_raw(addr as *mut u8, size + 1, prot, flags) };
640-
assert_eq!(format!("{:?}", r.unwrap_err()), "InvalidSize");
641-
642628
let r = unsafe { MmapRegion::build_raw(addr as *mut u8, size, prot, flags).unwrap() };
643629

644630
assert_eq!(r.size(), size);

0 commit comments

Comments
 (0)