From edfa526138dd34beadbcc4647c072094e4f6533a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Wed, 7 Aug 2024 17:38:53 +0300 Subject: [PATCH] =?UTF-8?q?mdbx:=20=D1=83=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6?= =?UTF-8?q?=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20`SIGSEGV`=20=D0=B2=D0=BD=D1=83?= =?UTF-8?q?=D1=82=D1=80=D0=B8=20`coherency=5Fcheck()`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Падение происходило в случае когда: - Некоторый процесс увеличивал размер БД с изменением геометрии (с увеличением предельного размера БД и её отображения в ОЗУ), затем задействовал страницу из добавленного сегмента в качестве корневой для FreeDB/GC и/или MainDB и фиксировал транзакцию. - Другой процесс, уже работавший с БД до изменения геометрии первым процессом, запускал транзакцию чтения. Падение происходило при проверке «когерентности» отображения страниц БД в ОЗУ, при проверке отметок модификации внутри корневых страниц, так как в этом случае они были вне границ текущего отображения БД в адресном пространстве этого процесса. Похоже что в ходе какого-то рефакторинга потерялась соответствующая проверка. Этот коммит добавляет её как временное решение, до переноса проверки «когерентности» после изменения размера отображения (добавлено в TODO). --- TODO.md | 1 + src/coherency.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index 13deca20..da83def7 100644 --- a/TODO.md +++ b/TODO.md @@ -11,6 +11,7 @@ For the same reason ~~Github~~ is blacklisted forever. So currently most of the links are broken due to noted malicious ~~Github~~ sabotage. + - Внутри `txn_renew()` вынести проверку когерентности mmap за/после изменение размера. - [Migration guide from LMDB to MDBX](https://libmdbx.dqdkfa.ru/dead-github/issues/199). - [Support for RAW devices](https://libmdbx.dqdkfa.ru/dead-github/issues/124). - [Support MessagePack for Keys & Values](https://libmdbx.dqdkfa.ru/dead-github/issues/115). diff --git a/src/coherency.c b/src/coherency.c index 7ae4da87..9e55a894 100644 --- a/src/coherency.c +++ b/src/coherency.c @@ -76,7 +76,13 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, : "(wagering meta)"); ok = false; } - if (likely(freedb_root && freedb_mod_txnid)) { + + /* Проверяем отметки внутри корневых страниц только если сами страницы + * в пределах текущего отображения. Иначе возможны SIGSEGV до переноса + * вызова coherency_check_head() после dxb_resize() внутри txn_renew(). */ + if (likely(freedb_root && freedb_mod_txnid && + (size_t)ptr_dist(env->dxb_mmap.base, freedb_root) < + env->dxb_mmap.limit)) { VALGRIND_MAKE_MEM_DEFINED(freedb_root, sizeof(freedb_root->txnid)); MDBX_ASAN_UNPOISON_MEMORY_REGION(freedb_root, sizeof(freedb_root->txnid)); const txnid_t root_txnid = freedb_root->txnid; @@ -91,7 +97,9 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, ok = false; } } - if (likely(maindb_root && maindb_mod_txnid)) { + if (likely(maindb_root && maindb_mod_txnid && + (size_t)ptr_dist(env->dxb_mmap.base, maindb_root) < + env->dxb_mmap.limit)) { VALGRIND_MAKE_MEM_DEFINED(maindb_root, sizeof(maindb_root->txnid)); MDBX_ASAN_UNPOISON_MEMORY_REGION(maindb_root, sizeof(maindb_root->txnid)); const txnid_t root_txnid = maindb_root->txnid;