From 9aa838aed99a4879d8357ff295a0ca1c98ba1ae5 Mon Sep 17 00:00:00 2001 From: Yevhenii Reizner Date: Sun, 15 Aug 2021 20:55:06 +0300 Subject: [PATCH] Fix integer overflow during file length calculation on 32bit targets. --- CHANGELOG.md | 2 ++ src/lib.rs | 18 +++++++++++++++--- src/stub.rs | 4 ++-- src/unix.rs | 4 ++-- src/windows.rs | 4 ++-- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46b9b9fa..caca865a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed +- Integer overflow during file length calculation on 32bit targets. ## [0.3.0] - 2021-06-10 ### Changed diff --git a/src/lib.rs b/src/lib.rs index f072cf62..5933ccbb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -188,13 +188,25 @@ impl MmapOptions { self.len.map(Ok).unwrap_or_else(|| { let desc = file.as_raw_desc(); let file_len = file_len(desc.0)?; - let len = file_len as u64 - self.offset; - if len > (usize::MAX as u64) { + + if file_len < self.offset { return Err(Error::new( ErrorKind::InvalidData, - "memory map length overflows usize", + "memory map offset is larger than length", )); } + let len = file_len - self.offset; + + #[cfg(not(target_pointer_width = "64"))] + { + if len > (usize::MAX as u64) { + return Err(Error::new( + ErrorKind::InvalidData, + "memory map length overflows usize", + )); + } + } + Ok(len as usize) }) } diff --git a/src/stub.rs b/src/stub.rs index 35d37024..a555a4f3 100644 --- a/src/stub.rs +++ b/src/stub.rs @@ -75,6 +75,6 @@ impl MmapInner { } } -pub fn file_len(file: &File) -> io::Result { - Ok(file.metadata()?.len() as usize) +pub fn file_len(file: &File) -> io::Result { + Ok(file.metadata()?.len()) } diff --git a/src/unix.rs b/src/unix.rs index 94f73ede..97b31838 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -233,13 +233,13 @@ fn page_size() -> usize { unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize } } -pub fn file_len(file: RawFd) -> io::Result { +pub fn file_len(file: RawFd) -> io::Result { unsafe { let mut stat: libc::stat = std::mem::zeroed(); let result = libc::fstat(file, &mut stat); if result == 0 { - Ok(stat.st_size as usize) + Ok(stat.st_size as u64) } else { Err(io::Error::last_os_error()) } diff --git a/src/windows.rs b/src/windows.rs index 74ef8668..7f13f683 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -435,6 +435,6 @@ fn allocation_granularity() -> usize { } } -pub fn file_len(file: &File) -> io::Result { - Ok(file.metadata()?.len() as usize) +pub fn file_len(file: &File) -> io::Result { + Ok(file.metadata()?.len()) }