https://bugs.openldap.org/show_bug.cgi?id=10562
Issue ID: 10562 Summary: Bug (and one possible fix) for MDB_RDONLY on a writable filesystem Product: LMDB Version: 1.0.1 Hardware: All OS: All Status: UNCONFIRMED Keywords: needs_review Severity: normal Priority: --- Component: liblmdb Assignee: bugs@openldap.org Reporter: dan@shearer.org Target Milestone: ---
Created attachment 1187 --> https://bugs.openldap.org/attachment.cgi?id=1187&action=edit Patch to fix docs in lmdb.h
I found this problem in LumoSQL when following the LMDB documentation.
From the MDB_RDONLY description of mdb_env_open:
"Open the environment in read-only mode. No write operations will be allowed. LMDB will still modify the lock file - except on read-only filesystems, where LMDB does not use locks."
Therefore, on writeable filesystems, MDB_RDONLY will still cause writes to a lockfile. This is a problem when a process wants read-only access to a database it has read permission on, but not write permission, such as unprivileged user reading a root-owned system database on an ordinary writable filesystem.
Because the filesystem is writable, the lock file is opened O_RDWR|O_CREAT. For an unprivileged reader this returns EACCES. mdb_env_setup_locks() only tests for EROFS, so the open fails with EACCES (13).
I suspect the minimal fix is to push the responsibility back onto the user (ie me in this case) and tell them in the documentation to add MDB_NOLOCK if they want read-only access on a writable filesystem. They also have to be very sure that there are no active writers, such as a root process somewhere else. I have attached a documentation patch for this. However, it's pretty harsh on the user because EACCES is a bit inscrutable, and fails the principle of least surprise.
A minimal change to LMDB code would be to return something other than EACCES in this case so that the user is informed about what is happening, and can then decide whether MDB_NOLOCK is safe, or something else.
Apart from that I can't think of what to do, due to safety issues. But this doesn't seem like an uncommon use pattern. I found it in LumoSQL when backing rpm with LMDB, where an unprivileged user can do a query while a root user is doing an update ( https://codeberg.org/LumoSQL/lumosql/src/branch/trunk/examples/rpm ).
Best,
-- Dan Shearer dan@shearer.org / https://shearer.org