Skip to content

Commit

Permalink
Avoid potential integer overflow in Mmap.mmap (JuliaLang#41186)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kkretschmer authored Jul 19, 2021
1 parent 6182eef commit 586acfb
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 1 deletion.
6 changes: 5 additions & 1 deletion stdlib/Mmap/src/Mmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,11 @@ function mmap(io::IO,
isopen(io) || throw(ArgumentError("$io must be open to mmap"))
isbitstype(T) || throw(ArgumentError("unable to mmap $T; must satisfy isbitstype(T) == true"))

len = prod(dims) * sizeof(T)
len = sizeof(T)
for l in dims
len, overflow = Base.Checked.mul_with_overflow(promote(len, l)...)
overflow && throw(ArgumentError("requested size prod($((sizeof(T), dims...))) too large, would overflow typeof(size(T)) == $(typeof(len))"))
end
len >= 0 || throw(ArgumentError("requested size must be ≥ 0, got $len"))
len == 0 && return Array{T}(undef, ntuple(x->0,Val(N)))
len < typemax(Int) - PAGESIZE || throw(ArgumentError("requested size must be < $(typemax(Int)-PAGESIZE), got $len"))
Expand Down
1 change: 1 addition & 0 deletions stdlib/Mmap/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ c = mmap(s, Vector{UInt8}, (UInt16(11),))
finalize(c); c=nothing; GC.gc()
@test_throws ArgumentError mmap(s, Vector{UInt8}, (Int16(-11),))
@test_throws ArgumentError mmap(s, Vector{UInt8}, (typemax(UInt),))
@test_throws ArgumentError mmap(s, Matrix{UInt8}, (typemax(Int) - Mmap.PAGESIZE - 1, 2)) # overflow
close(s)
s = open(file, "r+")
@test isreadonly(s) == false
Expand Down

0 comments on commit 586acfb

Please sign in to comment.