mdbx: исправление ложного срабатывания контроля "invalid page-address" в page_check().

При проверке использовалось глобальное значение me_dxb_mmap.current,
к которому не должны обращаться читающие транзакции. В результате,
в сложных много-поточных сценариях с изменением размера БД и её
переполнением, проверка могла выдавать ложно-положительный результат.

С точки зрения пользователя, ошибка могла проявляться как возврат
`MDBX_CORRUPTED` из читающей транзакции, когда включен "безопасный
режим" (дополнительный контроль), а в параллельной пишущей транзакции
происходит увеличение размера БД с последующим переполнением и откатом
этой транзакции. При этом никакого повреждения структуры БД нет.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2022-10-09 19:41:13 +03:00
parent 63b4d2289d
commit 92d203a12c

View File

@ -18476,9 +18476,9 @@ __cold static int page_check(MDBX_cursor *const mc, const MDBX_page *const mp) {
unsigned flags_mask = P_ILL_BITS;
unsigned flags_expected = 0;
if (offset < 0 ||
offset > (ptrdiff_t)(env->me_dxb_mmap.current - ((mp->mp_flags & P_SUBP)
? PAGEHDRSZ + 1
: env->me_psize))) {
offset > (ptrdiff_t)(pgno2bytes(env, mc->mc_txn->mt_next_pgno) -
((mp->mp_flags & P_SUBP) ? PAGEHDRSZ + 1
: env->me_psize))) {
/* should be dirty page without MDBX_WRITEMAP, or a subpage of. */
flags_mask -= P_SUBP;
if ((env->me_flags & MDBX_WRITEMAP) != 0 ||