mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-30 03:34:13 +08:00
mdbx: fix null-deref while override invalid meta-pages.
Related to https://github.com/erthink/libmdbx/issues/217
This commit is contained in:
parent
1995754bc3
commit
c8743cb9c4
29
src/core.c
29
src/core.c
@ -11415,6 +11415,13 @@ __cold int mdbx_env_get_maxreaders(const MDBX_env *env, unsigned *readers) {
|
||||
}
|
||||
#endif /* LIBMDBX_NO_EXPORTS_LEGACY_API */
|
||||
|
||||
__cold static int alloc_page_buf(MDBX_env *env) {
|
||||
return env->me_pbuf
|
||||
? MDBX_SUCCESS
|
||||
: mdbx_memalign_alloc(env->me_os_psize, env->me_psize * NUM_METAS,
|
||||
&env->me_pbuf);
|
||||
}
|
||||
|
||||
/* Further setup required for opening an MDBX environment */
|
||||
__cold static int mdbx_setup_dxb(MDBX_env *env, const int lck_rc,
|
||||
const mdbx_mode_t mode_bits) {
|
||||
@ -11437,13 +11444,13 @@ __cold static int mdbx_setup_dxb(MDBX_env *env, const int lck_rc,
|
||||
return err;
|
||||
}
|
||||
|
||||
void *buffer = mdbx_calloc(NUM_METAS, env->me_psize);
|
||||
if (!buffer)
|
||||
return MDBX_ENOMEM;
|
||||
err = alloc_page_buf(env);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
|
||||
meta = *mdbx_init_metas(env, buffer);
|
||||
err = mdbx_pwrite(env->me_lazy_fd, buffer, env->me_psize * NUM_METAS, 0);
|
||||
mdbx_free(buffer);
|
||||
meta = *mdbx_init_metas(env, env->me_pbuf);
|
||||
err = mdbx_pwrite(env->me_lazy_fd, env->me_pbuf, env->me_psize * NUM_METAS,
|
||||
0);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
|
||||
@ -12129,6 +12136,9 @@ static uint32_t merge_sync_flags(const uint32_t a, const uint32_t b) {
|
||||
|
||||
__cold static int __must_check_result mdbx_override_meta(
|
||||
MDBX_env *env, unsigned target, txnid_t txnid, const MDBX_meta *shape) {
|
||||
int rc = alloc_page_buf(env);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
MDBX_page *const page = env->me_pbuf;
|
||||
mdbx_meta_model(env, page, target);
|
||||
MDBX_meta *const model = page_meta(page);
|
||||
@ -12144,7 +12154,7 @@ __cold static int __must_check_result mdbx_override_meta(
|
||||
sizeof(model->mm_pages_retired));
|
||||
}
|
||||
unaligned_poke_u64(4, model->mm_datasync_sign, mdbx_meta_sign(model));
|
||||
int rc = mdbx_validate_meta(env, model, page, target, nullptr);
|
||||
rc = mdbx_validate_meta(env, model, page, target, nullptr);
|
||||
if (unlikely(MDBX_IS_ERROR(rc)))
|
||||
return MDBX_PROBLEM;
|
||||
|
||||
@ -12625,10 +12635,7 @@ __cold int mdbx_env_open(MDBX_env *env, const char *pathname,
|
||||
size = tsize + env->me_maxdbs *
|
||||
(sizeof(MDBX_db) + sizeof(MDBX_cursor *) +
|
||||
sizeof(unsigned) + 1);
|
||||
rc = mdbx_memalign_alloc(
|
||||
env->me_os_psize,
|
||||
env->me_psize * (1 /* page buffer */ + 1 /* page killer buffer */),
|
||||
&env->me_pbuf);
|
||||
rc = alloc_page_buf(env);
|
||||
if (rc == MDBX_SUCCESS) {
|
||||
memset(env->me_pbuf, -1, env->me_psize * 2);
|
||||
MDBX_txn *txn = mdbx_calloc(1, size);
|
||||
|
Loading…
x
Reference in New Issue
Block a user