From 81a8127084d9a6a7777bb375e029062330e51979 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, 27 Nov 2024 18:26:24 +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"may=20be=20used=20uninitialized"=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5=D0=B6=D0=B4?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=B2=20LTO-=D1=81=D0=B1=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=D1=85=20=D0=B8=D0=B7-=D0=B7=D0=B0=20=D1=83=D1=81?= =?UTF-8?q?=D0=BB=D0=BE=D0=B6=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20SSA/CTF=20?= =?UTF-8?q?=D0=B2=D1=81=D0=BB=D0=B5=D0=B4=D1=81=D1=82=D0=B2=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?LOG=5FIFERR().?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-txn.c | 18 +++++++++------- src/cold.c | 10 +++++---- src/dbi.c | 47 ++++++++++++++++++++++++++--------------- src/logging_and_debug.c | 4 +++- src/logging_and_debug.h | 21 ++++++++++++++++-- src/misc.c | 10 ++++++--- 6 files changed, 75 insertions(+), 35 deletions(-) diff --git a/src/api-txn.c b/src/api-txn.c index ab5d4df4..d75f05ff 100644 --- a/src/api-txn.c +++ b/src/api-txn.c @@ -40,13 +40,14 @@ int mdbx_txn_straggler(const MDBX_txn *txn, int *percent) __cold int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi, uint32_t *mask) { + if (unlikely(!mask)) + return LOG_IFERR(MDBX_EINVAL); + + *mask = 0; int rc = check_txn(txn, MDBX_TXN_BLOCKED); if (unlikely(rc != MDBX_SUCCESS)) return LOG_IFERR(rc); - if (unlikely(!mask)) - return LOG_IFERR(MDBX_EINVAL); - cursor_couple_t cx; rc = cursor_init(&cx.outer, txn, dbi); if (unlikely(rc != MDBX_SUCCESS)) @@ -56,7 +57,6 @@ __cold int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val key, data; rc = outer_first(&cx.outer, &key, &data); - *mask = 0; while (rc == MDBX_SUCCESS) { const node_t *node = page_node(cx.outer.pg[cx.outer.top], cx.outer.ki[cx.outer.top]); @@ -88,13 +88,15 @@ __cold int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi, } int mdbx_canary_get(const MDBX_txn *txn, MDBX_canary *canary) { - int rc = check_txn(txn, MDBX_TXN_BLOCKED); - if (unlikely(rc != MDBX_SUCCESS)) - return LOG_IFERR(rc); - if (unlikely(canary == nullptr)) return LOG_IFERR(MDBX_EINVAL); + int rc = check_txn(txn, MDBX_TXN_BLOCKED); + if (unlikely(rc != MDBX_SUCCESS)) { + memset(canary, 0, sizeof(*canary)); + return LOG_IFERR(rc); + } + *canary = txn->canary; return MDBX_SUCCESS; } diff --git a/src/cold.c b/src/cold.c index db3b0b87..53f0a6a0 100644 --- a/src/cold.c +++ b/src/cold.c @@ -554,13 +554,15 @@ __cold int mdbx_env_set_flags(MDBX_env *env, MDBX_env_flags_t flags, } __cold int mdbx_env_get_flags(const MDBX_env *env, unsigned *arg) { - int rc = check_env(env, false); - if (unlikely(rc != MDBX_SUCCESS)) - return LOG_IFERR(rc); - if (unlikely(!arg)) return LOG_IFERR(MDBX_EINVAL); + int rc = check_env(env, false); + if (unlikely(rc != MDBX_SUCCESS)) { + *arg = 0; + return LOG_IFERR(rc); + } + *arg = env->flags & ENV_USABLE_FLAGS; return MDBX_SUCCESS; } diff --git a/src/dbi.c b/src/dbi.c index 109198d5..888f0e03 100644 --- a/src/dbi.c +++ b/src/dbi.c @@ -908,21 +908,26 @@ int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi) { int mdbx_dbi_flags_ex(const MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags, unsigned *state) { - int rc = check_txn(txn, MDBX_TXN_BLOCKED - MDBX_TXN_ERROR - MDBX_TXN_PARKED); - if (unlikely(rc != MDBX_SUCCESS)) - return LOG_IFERR(rc); - if (unlikely(!flags || !state)) return LOG_IFERR(MDBX_EINVAL); - rc = dbi_check(txn, dbi); - if (unlikely(rc != MDBX_SUCCESS)) + int rc = check_txn(txn, MDBX_TXN_BLOCKED - MDBX_TXN_ERROR - MDBX_TXN_PARKED); + if (unlikely(rc != MDBX_SUCCESS)) { + *flags = 0; + *state = 0; return LOG_IFERR(rc); + } + + rc = dbi_check(txn, dbi); + if (unlikely(rc != MDBX_SUCCESS)) { + *flags = 0; + *state = 0; + return LOG_IFERR(rc); + } *flags = txn->dbs[dbi].flags & DB_PERSISTENT_FLAGS; *state = txn->dbi_state[dbi] & (DBI_FRESH | DBI_CREAT | DBI_DIRTY | DBI_STALE); - return MDBX_SUCCESS; } @@ -968,33 +973,41 @@ static void stat_get(const tree_t *db, MDBX_stat *st, size_t bytes) { __cold int mdbx_dbi_stat(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *dest, size_t bytes) { - int rc = check_txn(txn, MDBX_TXN_BLOCKED); - if (unlikely(rc != MDBX_SUCCESS)) - return LOG_IFERR(rc); - if (unlikely(!dest)) return LOG_IFERR(MDBX_EINVAL); + int rc = check_txn(txn, MDBX_TXN_BLOCKED); + if (unlikely(rc != MDBX_SUCCESS)) + goto bailout; + rc = dbi_check(txn, dbi); if (unlikely(rc != MDBX_SUCCESS)) - return LOG_IFERR(rc); + goto bailout; const size_t size_before_modtxnid = offsetof(MDBX_stat, ms_mod_txnid); - if (unlikely(bytes != sizeof(MDBX_stat)) && bytes != size_before_modtxnid) - return LOG_IFERR(MDBX_EINVAL); + if (unlikely(bytes != sizeof(MDBX_stat)) && bytes != size_before_modtxnid) { + rc = MDBX_EINVAL; + goto bailout; + } - if (unlikely(txn->flags & MDBX_TXN_BLOCKED)) - return LOG_IFERR(MDBX_BAD_TXN); + if (unlikely(txn->flags & MDBX_TXN_BLOCKED)) { + rc = MDBX_BAD_TXN; + goto bailout; + } if (unlikely(txn->dbi_state[dbi] & DBI_STALE)) { rc = tbl_fetch((MDBX_txn *)txn, dbi); if (unlikely(rc != MDBX_SUCCESS)) - return LOG_IFERR(rc); + goto bailout; } dest->ms_psize = txn->env->ps; stat_get(&txn->dbs[dbi], dest, bytes); return MDBX_SUCCESS; + +bailout: + memset(dest, 0, bytes); + return LOG_IFERR(rc); } __cold const tree_t *dbi_dig(const MDBX_txn *txn, const size_t dbi, diff --git a/src/logging_and_debug.c b/src/logging_and_debug.c index 0fc4098a..20d8419e 100644 --- a/src/logging_and_debug.c +++ b/src/logging_and_debug.c @@ -61,7 +61,9 @@ __cold void debug_log(int level, const char *function, int line, __cold int log_error(const int err, const char *func, unsigned line) { assert(err != MDBX_SUCCESS); - if (unlikely(globals.loglevel >= MDBX_LOG_DEBUG)) { + if (unlikely(globals.loglevel >= MDBX_LOG_DEBUG) && + (globals.loglevel >= MDBX_LOG_TRACE || + !(err == MDBX_RESULT_TRUE || err == MDBX_NOTFOUND))) { char buf[256]; debug_log(MDBX_LOG_ERROR, func, line, "error %d (%s)\n", err, mdbx_strerror_r(err, buf, sizeof(buf))); diff --git a/src/logging_and_debug.h b/src/logging_and_debug.h index 6b9ef145..b3cef271 100644 --- a/src/logging_and_debug.h +++ b/src/logging_and_debug.h @@ -161,8 +161,25 @@ MDBX_INTERNAL const char *pagetype_caption(const uint8_t type, MDBX_INTERNAL int log_error(const int err, const char *func, unsigned line); -static inline int log_if_error(int err, const char *func, unsigned line) { - return likely(err == MDBX_SUCCESS) ? err : log_error(err, func, line); +static inline int log_if_error(const int err, const char *func, unsigned line) { + if (likely(err == MDBX_SUCCESS)) + return err; + int rc = log_error(err, func, line); +#if __has_c_attribute(assume) + [[assume(rc == err && rc != MDBX_SUCCESS)]]; +#endif +#if defined(__clang__) || __has_builtin(assume) + __builtin_assume(rc == err && rc != MDBX_SUCCESS); +#endif + if (rc != err || rc == MDBX_SUCCESS) { +#if defined(__GNUC__) + __builtin_unreachable(); +#elif defined(_MSC_VER) && !defined(__clang__) + __assume(0); +#endif + rc = err; + } + return rc; } #define LOG_IFERR(err) log_if_error((err), __func__, __LINE__) diff --git a/src/misc.c b/src/misc.c index 367bcdfb..f1a58014 100644 --- a/src/misc.c +++ b/src/misc.c @@ -34,17 +34,21 @@ __cold int mdbx_is_readahead_reasonable(size_t volume, intptr_t redundancy) { int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, uint64_t increment) { int rc = check_txn(txn, MDBX_TXN_BLOCKED); - if (unlikely(rc != MDBX_SUCCESS)) + if (unlikely(rc != MDBX_SUCCESS)) { + bailout: + if (likely(result)) + *result = ~UINT64_C(0); return LOG_IFERR(rc); + } rc = dbi_check(txn, dbi); if (unlikely(rc != MDBX_SUCCESS)) - return LOG_IFERR(rc); + goto bailout; if (unlikely(txn->dbi_state[dbi] & DBI_STALE)) { rc = tbl_fetch(txn, dbi); if (unlikely(rc != MDBX_SUCCESS)) - return LOG_IFERR(rc); + goto bailout; } tree_t *dbs = &txn->dbs[dbi];