Skip to content

Commit 586acfb

Browse files
authored
Avoid potential integer overflow in Mmap.mmap (#41186)
There is a potential integer overflow in Mmap.mmap which can lead to an out-of-bounds access. The size of the memory-mapped array `len` is calculated as `prod(dims)`. If this multiplication overflows, the allocated size will be too small and accesses towards the end of the array will fail with e.g. a segfault or other errors. I noticed this when using `dims` taken from a binary file header in UInt32 format. To fix, use overflow-aware multiplication to determine the size of the mmapped array and throw an error in case of overflow.
1 parent 6182eef commit 586acfb

File tree

2 files changed

+6
-1
lines changed

2 files changed

+6
-1
lines changed

stdlib/Mmap/src/Mmap.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,11 @@ function mmap(io::IO,
191191
isopen(io) || throw(ArgumentError("$io must be open to mmap"))
192192
isbitstype(T) || throw(ArgumentError("unable to mmap $T; must satisfy isbitstype(T) == true"))
193193

194-
len = prod(dims) * sizeof(T)
194+
len = sizeof(T)
195+
for l in dims
196+
len, overflow = Base.Checked.mul_with_overflow(promote(len, l)...)
197+
overflow && throw(ArgumentError("requested size prod($((sizeof(T), dims...))) too large, would overflow typeof(size(T)) == $(typeof(len))"))
198+
end
195199
len >= 0 || throw(ArgumentError("requested size must be ≥ 0, got $len"))
196200
len == 0 && return Array{T}(undef, ntuple(x->0,Val(N)))
197201
len < typemax(Int) - PAGESIZE || throw(ArgumentError("requested size must be < $(typemax(Int)-PAGESIZE), got $len"))

stdlib/Mmap/test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ c = mmap(s, Vector{UInt8}, (UInt16(11),))
133133
finalize(c); c=nothing; GC.gc()
134134
@test_throws ArgumentError mmap(s, Vector{UInt8}, (Int16(-11),))
135135
@test_throws ArgumentError mmap(s, Vector{UInt8}, (typemax(UInt),))
136+
@test_throws ArgumentError mmap(s, Matrix{UInt8}, (typemax(Int) - Mmap.PAGESIZE - 1, 2)) # overflow
136137
close(s)
137138
s = open(file, "r+")
138139
@test isreadonly(s) == false

0 commit comments

Comments
 (0)