[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openldap-bugs
Subject:    [Issue 9397] New: LMDB: A second process opening a file with MDB_WRITEMAP can cause the first to SIG
From:       openldap-its () openldap ! org
Date:       2020-11-19 2:25:29
Message-ID: bug-9397-2 () http ! bugs ! openldap ! org/
[Download RAW message or body]

https://bugs.openldap.org/show_bug.cgi?id=9397

          Issue ID: 9397
           Summary: LMDB: A second process opening a file with
                    MDB_WRITEMAP can cause the first to SIGBUS
           Product: LMDB
           Version: 0.9.26
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Severity: normal
          Priority: ---
         Component: liblmdb
          Assignee: bugs@openldap.org
          Reporter: github@nicwatson.org
  Target Milestone: ---

Created attachment 780
  --> https://bugs.openldap.org/attachment.cgi?id=780&action=edit
Full reproduction of SIGBUS MDB_WRITEMAP issue (works on Linux only)

The fundamental problem is that a ftruncate() on Linux that makes a file
smaller will cause accesses past the new end of the file to SIGBUS (see the
mmap man page).

The sequence that causes a SIGBUS involves two processes.

1.  The first process opens a new LMDB file with MDB_WRITEMAP.
2.  The second process opens the same LMDB file with MDB_WRITEMAP and with an
explicit map_size smaller than the first process's map size.
    * This causes an ftruncate that makes the underlying file *smaller*.
3.  (Optional) The second process closes the environment and exits.
4.  The first process opens a write transaction and writes a bunch of data.
5.  The first process commits the transaction.  This causes a memory read from
the mapped memory that's now past the end of the file.  On Linux, this triggers
a SIGBUS.

Attached is code that fully reproduces the problem on Linux.

The most straightforward solution is to allow ftruncate to *reduce* the file
size if it is the only reader.  Another possibility is check the file size and
ftruncate if necessary every time a write transaction is opened.  A third
possibility is to catch the SIGBUS signal.


Repro note:  I used clone() to create the subprocess to most straightforwardly
demonstrate that the problem is not due to inherited file descriptors.  The
problem still manifests when the processes are completely independent.

-- 
You are receiving this mail because:
You are on the CC list for the issue.=
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic