[krbdev.mit.edu #8918] KDC and kadmind fork with DB open, breaking LMDB KDB module
Greg Hudson via RT
rt-comment at krbdev.mit.edu
Thu Jun 18 21:18:32 EDT 2020
Thu Jun 18 21:18:31 2020: Request 8918 was acted upon.
Transaction: Ticket created by ghudson at mit.edu
Queue: krb5
Subject: KDC and kadmind fork with DB open, breaking LMDB KDB module
Owner: Nobody
Requestors: ghudson at mit.edu
Status: open
Ticket <URL: https://krbdev.mit.edu/rt/Ticket/Display.html?id=8918 >
lmdb.h says "Use an MDB_env* in the process which opened it, not after fork()."
The reason is that LMDB tracks stale reader entries by pid. (Rather than using
kill() to detect if the locking pid corresponds to an active process, it
creates a POSIX one-byte range lock using the pid as an offset when the DB is
opened, and tests for the existence of the lock. A fork()/exit() causes this
lock to be dropped, even though the environment fd is still open.)
krb5kdc and kadmind both open the database before daemonizing, so they violate
this restriction. The consequence is that their reader entries can be stolen
and invalidated by other processes (including each other). The bereft process
will then receive MDB_BAD_RSLOT ("Invalid reuse of reader locktable slot")
errors when trying to renew its read transaction.
This bug does not manifest in the automated tests, because we mostly start
krb5kdc and kadmind with the nofork option set. It also may not manifest if
krb5kdc and kadmind are started simultaneously, as they may both claim their
reader transaction slots before either one of them forks and exits.
My manual process for reproducing the bug is:
make testrealm
pkill krb5kdc
pkill kadmind
krb5kdc
kadmind
kinit user
See also: https://mailman.mit.edu/pipermail/kerberos/2020-June/022507.html
More information about the krb5-bugs
mailing list