Found while building coverage drivers for the never-called getter surface (#147). Verified by source inspection.
The bug
src/lock/lock_method.c, both priority accessors:
if ((ret = __lock_getlocker(env->lk_handle, lockid, 0, &locker)) == 0)
locker->priority = priority; /* :482 set */
...
*priorityp = locker->priority; /* :507 get */
__lock_getlocker is called with create = 0. In __lock_getlocker_int (src/lock/lock_id.c) the only assignment to *retp is line 408, *retp = sh_locker, at the end of the function, and the create branch is guarded by if (sh_locker == NULL && create). So for an id that is not present with create == 0, the function returns 0 with *retp == NULL, and both accessors dereference it unconditionally.
DB_ENV->set_lk_priority() / get_lk_priority() are public APIs taking a caller-supplied lockid, so an unknown or already-freed id is reachable from application code.
Same pattern nearby
__lock_vec_pp (src/lock/lock.c:93) uses the same create = 0 call and passes the result into __lock_vec, so it can feed a NULL locker downstream. Worth auditing together.
Suggested fix
Treat "found, but NULL" as not-found — return EINVAL (or DB_NOTFOUND) when *retp == NULL after a create = 0 lookup, ideally by having __lock_getlocker report not-found distinctly so callers can't repeat the mistake.
Not fixed in #147, which was scoped to tests only.
Found while building coverage drivers for the never-called getter surface (#147). Verified by source inspection.
The bug
src/lock/lock_method.c, both priority accessors:__lock_getlockeris called withcreate = 0. In__lock_getlocker_int(src/lock/lock_id.c) the only assignment to*retpis line 408,*retp = sh_locker, at the end of the function, and the create branch is guarded byif (sh_locker == NULL && create). So for an id that is not present withcreate == 0, the function returns 0 with*retp == NULL, and both accessors dereference it unconditionally.DB_ENV->set_lk_priority()/get_lk_priority()are public APIs taking a caller-suppliedlockid, so an unknown or already-freed id is reachable from application code.Same pattern nearby
__lock_vec_pp(src/lock/lock.c:93) uses the samecreate = 0call and passes the result into__lock_vec, so it can feed a NULL locker downstream. Worth auditing together.Suggested fix
Treat "found, but NULL" as not-found — return
EINVAL(orDB_NOTFOUND) when*retp == NULLafter acreate = 0lookup, ideally by having__lock_getlockerreport not-found distinctly so callers can't repeat the mistake.Not fixed in #147, which was scoped to tests only.