Skip to content

scst_dlm: Fix use-after-free by waiting for lkb destruction#368

Open
bmeagherix wants to merge 1 commit into
SCST-project:masterfrom
bmeagherix:fix_dlm_uaf
Open

scst_dlm: Fix use-after-free by waiting for lkb destruction#368
bmeagherix wants to merge 1 commit into
SCST-project:masterfrom
bmeagherix:fix_dlm_uaf

Conversation

@bmeagherix
Copy link
Copy Markdown
Contributor

When scst_dlm_unlock_wait() timed out, the caller could proceed to free the containing storage of @lksb while DLM still held a reference to it in lkb->lkb_lksb. A subsequently delivered AST -- e.g. a recovery-synthesized UNLOCK_REPLY for a departed peer -- would then write sb_status into freed memory.

Make scst_dlm_remove_lock() honor its contract on every path: after the convert-to-NL clean-release step, issue
dlm_unlock(DLM_LKF_FORCEUNLOCK) and loop on the completion until a destroying CAST (sb_status == -DLM_EUNLOCK) is observed. FORCEUNLOCK ensures that such a CAST arrives even if an earlier operation is still in flight or a peer is departing, since
dlm_recover_waiters_pre() synthesizes the reply in the latter case. Non-destroying CASTs from previously canceled converts are logged and the wait continues.

Route the per-registrant teardown (scst_dlm_pr_rm_reg_ls), the remote-UA teardown (scst_dlm_rm_rem_ua_ls), and the remaining stack-allocated lksb teardown sites through scst_dlm_remove_lock() so they all observe the destroying CAST before their storage may be reused. As a side benefit, those sites gain the convert-to-NL step that preserves LVB validity on peers per the DLM EX/PW release rule.

When scst_dlm_unlock_wait() timed out, the caller could proceed to
free the containing storage of @lksb while DLM still held a reference
to it in lkb->lkb_lksb. A subsequently delivered AST -- e.g. a
recovery-synthesized UNLOCK_REPLY for a departed peer -- would then
write sb_status into freed memory.

Make scst_dlm_remove_lock() honor its contract on every path: after
the convert-to-NL clean-release step, issue
dlm_unlock(DLM_LKF_FORCEUNLOCK) and loop on the completion until a
destroying CAST (sb_status == -DLM_EUNLOCK) is observed. FORCEUNLOCK
ensures that such a CAST arrives even if an earlier operation is
still in flight or a peer is departing, since
dlm_recover_waiters_pre() synthesizes the reply in the latter case.
Non-destroying CASTs from previously canceled converts are logged
and the wait continues.

Route the per-registrant teardown (scst_dlm_pr_rm_reg_ls), the
remote-UA teardown (scst_dlm_rm_rem_ua_ls), and the remaining
stack-allocated lksb teardown sites through scst_dlm_remove_lock()
so they all observe the destroying CAST before their storage may
be reused. As a side benefit, those sites gain the convert-to-NL
step that preserves LVB validity on peers per the DLM EX/PW
release rule.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant