Skip to content

NULL dereference in __lock_set_lk_priority / __lock_get_lk_priority for an unknown locker id #148

Description

@gburd

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions