From: Nikita Pettik <korablev@tarantool.org> To: tarantool-patches@dev.tarantool.org Cc: v.shpilevoy@tarantool.org Subject: [Tarantool-patches] [PATCH v2 1/2] box/error: don't allow overflow of error ref counter Date: Fri, 17 Apr 2020 23:16:45 +0300 [thread overview] Message-ID: <878773d43bdc79130168b0beaf4e20aed795ddad.1587154034.git.korablev@tarantool.org> (raw) In-Reply-To: <cover.1587154034.git.korablev@tarantool.org> In-Reply-To: <cover.1587154034.git.korablev@tarantool.org> There's no overflow check while incrementing error's reference counter in error_ref(). Meanwhile, stubborn users still may achieve overflow: each call of box.error.last() increments reference counter of error residing in diagnostic area. As a result, 2^32 calls of box.error.last() in a row will lead to counter overflow ergo - to unpredictable results. Let's fix it and introduce dummy check in error_ref(). --- src/lib/core/diag.c | 1 + src/lib/core/diag.h | 8 +++++++- src/lua/error.c | 3 ++- src/lua/error.lua | 4 ++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/lib/core/diag.c b/src/lib/core/diag.c index e143db18d..5ddf543cb 100644 --- a/src/lib/core/diag.c +++ b/src/lib/core/diag.c @@ -60,6 +60,7 @@ error_set_prev(struct error *e, struct error *prev) */ error_unlink_effect(prev); } + assert(prev->refs < INT32_MAX); error_ref(prev); prev->effect = e; } diff --git a/src/lib/core/diag.h b/src/lib/core/diag.h index 7a5454d1c..fe852e640 100644 --- a/src/lib/core/diag.h +++ b/src/lib/core/diag.h @@ -112,10 +112,14 @@ struct error { struct error *effect; }; -static inline void +static inline int error_ref(struct error *e) { + assert(e->refs >= 0); + if (e->refs >= INT32_MAX) + return -1; e->refs++; + return 0; } static inline void @@ -247,6 +251,7 @@ static inline void diag_set_error(struct diag *diag, struct error *e) { assert(e != NULL); + assert(e->refs < INT32_MAX); error_ref(e); diag_clear(diag); error_unlink_effect(e); @@ -271,6 +276,7 @@ diag_add_error(struct diag *diag, struct error *e) */ assert(e->effect == NULL); assert(diag->last->effect == NULL); + assert(e->refs < INT32_MAX); error_ref(e); e->cause = diag->last; diag->last->effect = e; diff --git a/src/lua/error.c b/src/lua/error.c index 18a990a88..5c4af79e7 100644 --- a/src/lua/error.c +++ b/src/lua/error.c @@ -84,7 +84,8 @@ luaT_pusherror(struct lua_State *L, struct error *e) * It also important to reference the error first and only * then set the finalizer. */ - error_ref(e); + if (error_ref(e) != 0) + luaL_error(L, "Too many references to error object"); assert(CTID_CONST_STRUCT_ERROR_REF != 0); struct error **ptr = (struct error **) luaL_pushcdata(L, CTID_CONST_STRUCT_ERROR_REF); diff --git a/src/lua/error.lua b/src/lua/error.lua index bdc9c714d..7a2435b0a 100644 --- a/src/lua/error.lua +++ b/src/lua/error.lua @@ -118,6 +118,10 @@ local function error_set_prev(err, prev) if not ffi.istype('struct error', prev) and prev ~= nil then error("Usage: error1:set_prev(error2)") end + local INT32_MAX = 2147483647 + if err._refs >= INT32_MAX then + error("Too many references to error object") + end local ok = ffi.C.error_set_prev(err, prev); if ok ~= 0 then error("Cycles are not allowed") -- 2.17.1
next prev parent reply other threads:[~2020-04-17 20:16 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-04-17 20:16 [Tarantool-patches] [PATCH v2 0/2] Stacked diagnostic area follow-ups Nikita Pettik 2020-04-17 20:16 ` Nikita Pettik [this message] 2020-04-17 23:54 ` [Tarantool-patches] [PATCH v2 1/2] box/error: don't allow overflow of error ref counter Vladislav Shpilevoy 2020-04-20 1:15 ` Nikita Pettik 2020-04-17 20:16 ` [Tarantool-patches] [PATCH v2 2/2] box/error: ref error.prev while accessing it Nikita Pettik 2020-04-20 14:22 ` [Tarantool-patches] [PATCH v2 0/2] Stacked diagnostic area follow-ups Kirill Yukhin 2020-04-20 14:35 ` Nikita Pettik 2020-04-20 15:29 ` Kirill Yukhin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=878773d43bdc79130168b0beaf4e20aed795ddad.1587154034.git.korablev@tarantool.org \ --to=korablev@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 1/2] box/error: don'\''t allow overflow of error ref counter' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox