bug in mmap() and mremap() return value - and a fix

Massimiliano Ghilardi massimiliano.ghilardi at gmail.com
Mon Jan 6 21:06:07 UTC 2014


Running 32-bit CCL on 64-bit Linux (but it can happen in any setup),
I noticed that (osicat-posix:mmap) does not correctly handle return
addresses larger than the maximum C "long" value, but instead throws
an exception.

In such cases, it means the underlying C mmap() function returned
successfully a pointer in the top half of the addressable virtual
memory, but the Lisp wrapper for mmap() and mremap() chokes on such 
pointers.

A patch that solves this problem is attached.

Feedback on the analysis and the solution is welcome :)

Best regards,

Massimiliano Ghilardi



------------------ longer explanation -----------------------------

While invoking

(osicat-posix:mmap (cffi-sys:null-pointer) 4096
             (logior osicat-posix:prot-read osicat-posix:prot-write)
             osicat-posix:map-shared
             *fd* 0)

with a file descriptor *fd* correctly open on a 4096-byte file,
I encountered the error:
-------------------------------------------------------------------
The value -143798272 is not of the expected type (UNSIGNED-BYTE
                                                   32).
    [Condition of type TYPE-ERROR]

Restarts:
  0: [RETRY] Retry SLIME REPL evaluation request.
  1: [*ABORT] Return to SLIME's top level.
  2: [ABORT-BREAK] Reset this thread
  3: [ABORT] Kill this thread

Backtrace:
   0: (CFFI-SYS:MAKE-POINTER -143798272)
   1: (CCL::CALL-CHECK-REGS OSICAT-POSIX:MMAP #<A Null Foreign Pointer> 
4096 3 1 4 0)
   2: (CCL::CHEAP-EVAL (OSICAT-POSIX:MMAP (CFFI-SYS:NULL-POINTER) 4096 
(LOGIOR OSICAT-POSIX:PROT-READ OSICAT-POSIX:PROT-WRITE) 
OSICAT-POSIX:MAP-SHARED *FD* ...))
-------------------------------------------------------------------

A simple analysis (cat /proc/<ccl-pid>/maps) shows that mmap() actually
succeeded and returned the value #xf76dd000, which was converted to
-143798272 because OSICAT wrapper for mmap() is defined to return
a C "long", that is limited to the range -#x80000000 to #x7fffffff,
thus converting #xf76dd000 to a C long overflows and gives a negative
value.

But calling (cffi-sys:make-pointer) chokes on negative values, at least 
on CCL.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: osicat.mmap.patch
Type: text/x-patch
Size: 1787 bytes
Desc: not available
URL: <https://mailman.common-lisp.net/pipermail/osicat-devel/attachments/20140106/598484a7/attachment.bin>


More information about the osicat-devel mailing list