From ead627e5608b27dbf50cbb15d45b32bb41c5d8b2 Mon Sep 17 00:00:00 2001 From: xgdgsc Date: Tue, 22 Aug 2023 00:46:19 +0800 Subject: [PATCH] fix bus error on smaller readonly file in unix (#44354) Fixes: #28245 Co-authored-by: Jameson Nash Co-authored-by: Stefan Karpinski --- stdlib/Mmap/src/Mmap.jl | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/stdlib/Mmap/src/Mmap.jl b/stdlib/Mmap/src/Mmap.jl index 629f53e8371ed..9dd02d5aa9d04 100644 --- a/stdlib/Mmap/src/Mmap.jl +++ b/stdlib/Mmap/src/Mmap.jl @@ -208,18 +208,43 @@ function mmap(io::IO, mmaplen = (offset - offset_page) + len file_desc = gethandle(io) + szfile = convert(Csize_t, len + offset) + requestedSizeLarger = false + if !(io isa Mmap.Anonymous) + @static if !Sys.isapple() + requestedSizeLarger = szfile > filesize(io) + end + end # platform-specific mmapping @static if Sys.isunix() prot, flags, iswrite = settings(file_desc, shared) - iswrite && grow && grow!(io, offset, len) + if requestedSizeLarger + if iswrite + if grow + grow!(io, offset, len) + else + throw(ArgumentError("requested size $szfile larger than file size $(filesize(io)), but requested not to grow")) + end + else + throw(ArgumentError("unable to increase file size to $szfile due to read-only permissions")) + end + end + @static if Sys.isapple() + iswrite && grow && grow!(io, offset, len) + end # mmap the file ptr = ccall(:jl_mmap, Ptr{Cvoid}, (Ptr{Cvoid}, Csize_t, Cint, Cint, RawFD, Int64), C_NULL, mmaplen, prot, flags, file_desc, offset_page) systemerror("memory mapping failed", reinterpret(Int, ptr) == -1) else name, readonly, create = settings(io) - szfile = convert(Csize_t, len + offset) - readonly && szfile > filesize(io) && throw(ArgumentError("unable to increase file size to $szfile due to read-only permissions")) + if requestedSizeLarger + if readonly + throw(ArgumentError("unable to increase file size to $szfile due to read-only permissions")) + elseif !grow + throw(ArgumentError("requested size $szfile larger than file size $(filesize(io)), but requested not to grow")) + end + end handle = create ? ccall(:CreateFileMappingW, stdcall, Ptr{Cvoid}, (OS_HANDLE, Ptr{Cvoid}, DWORD, DWORD, DWORD, Cwstring), file_desc, C_NULL, readonly ? PAGE_READONLY : PAGE_READWRITE, szfile >> 32, szfile & typemax(UInt32), name) : ccall(:OpenFileMappingW, stdcall, Ptr{Cvoid}, (DWORD, Cint, Cwstring),