* [Tarantool-patches] [PATCH v2 0/2] raft: a few fixes for raft state symbolics @ 2020-10-29 8:37 Cyrill Gorcunov 2020-10-29 8:37 ` [Tarantool-patches] [PATCH v2 1/2] raft: raft_request_to_string -- don't hardcode size Cyrill Gorcunov ` (3 more replies) 0 siblings, 4 replies; 6+ messages in thread From: Cyrill Gorcunov @ 2020-10-29 8:37 UTC (permalink / raw) To: tml; +Cc: Vladislav Shpilevoy Just to make raft state symbolic representation being safe for arbitrary data since we use it for debug purposes as well. Cyrill Gorcunov (2): raft: raft_request_to_string -- don't hardcode size raft: decode even invalid states of raft src/box/lua/info.c | 2 +- src/box/raft.c | 41 +++++++++++++++++++++++++++-------------- src/box/raft.h | 6 +++++- 3 files changed, 33 insertions(+), 16 deletions(-) -- 2.26.2 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Tarantool-patches] [PATCH v2 1/2] raft: raft_request_to_string -- don't hardcode size 2020-10-29 8:37 [Tarantool-patches] [PATCH v2 0/2] raft: a few fixes for raft state symbolics Cyrill Gorcunov @ 2020-10-29 8:37 ` Cyrill Gorcunov 2020-10-30 7:21 ` Serge Petrenko 2020-10-29 8:37 ` [Tarantool-patches] [PATCH v2 2/2] raft: decode even invalid states of raft Cyrill Gorcunov ` (2 subsequent siblings) 3 siblings, 1 reply; 6+ messages in thread From: Cyrill Gorcunov @ 2020-10-29 8:37 UTC (permalink / raw) To: tml; +Cc: Vladislav Shpilevoy The size should be matched to the real size of a buffer, otherwise it is a room for mistake. Same time make sure we're not overriding the buffer. Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> --- src/box/raft.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/box/raft.c b/src/box/raft.c index 4a8e54cac..7c546de8c 100644 --- a/src/box/raft.c +++ b/src/box/raft.c @@ -275,36 +275,36 @@ static const char * raft_request_to_string(const struct raft_request *req) { assert(req->term != 0); - int size = 1024; char buf[1024]; + int size = sizeof(buf); char *pos = buf; int rc = snprintf(pos, size, "{term: %llu", (unsigned long long)req->term); - assert(rc >= 0); + assert(rc >= 0 && rc < size); pos += rc; size -= rc; if (req->vote != 0) { rc = snprintf(pos, size, ", vote: %u", req->vote); - assert(rc >= 0); + assert(rc >= 0 && rc < size); pos += rc; size -= rc; } if (req->state != 0) { rc = snprintf(pos, size, ", state: %s", raft_state_strs[req->state]); - assert(rc >= 0); + assert(rc >= 0 && rc < size); pos += rc; size -= rc; } if (req->vclock != NULL) { rc = snprintf(pos, size, ", vclock: %s", vclock_to_string(req->vclock)); - assert(rc >= 0); + assert(rc >= 0 && rc < size); pos += rc; size -= rc; } rc = snprintf(pos, size, "}"); - assert(rc >= 0); + assert(rc >= 0 && rc < size); pos += rc; return tt_cstr(buf, pos - buf); } -- 2.26.2 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 1/2] raft: raft_request_to_string -- don't hardcode size 2020-10-29 8:37 ` [Tarantool-patches] [PATCH v2 1/2] raft: raft_request_to_string -- don't hardcode size Cyrill Gorcunov @ 2020-10-30 7:21 ` Serge Petrenko 0 siblings, 0 replies; 6+ messages in thread From: Serge Petrenko @ 2020-10-30 7:21 UTC (permalink / raw) To: Cyrill Gorcunov, tml; +Cc: Vladislav Shpilevoy 29.10.2020 11:37, Cyrill Gorcunov пишет: > The size should be matched to the real size of a buffer, > otherwise it is a room for mistake. Same time make sure > we're not overriding the buffer. Hi! Thanks for the patch! LGTM. > > Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> > --- > src/box/raft.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/src/box/raft.c b/src/box/raft.c > index 4a8e54cac..7c546de8c 100644 > --- a/src/box/raft.c > +++ b/src/box/raft.c > @@ -275,36 +275,36 @@ static const char * > raft_request_to_string(const struct raft_request *req) > { > assert(req->term != 0); > - int size = 1024; > char buf[1024]; > + int size = sizeof(buf); > char *pos = buf; > int rc = snprintf(pos, size, "{term: %llu", > (unsigned long long)req->term); > - assert(rc >= 0); > + assert(rc >= 0 && rc < size); > pos += rc; > size -= rc; > if (req->vote != 0) { > rc = snprintf(pos, size, ", vote: %u", req->vote); > - assert(rc >= 0); > + assert(rc >= 0 && rc < size); > pos += rc; > size -= rc; > } > if (req->state != 0) { > rc = snprintf(pos, size, ", state: %s", > raft_state_strs[req->state]); > - assert(rc >= 0); > + assert(rc >= 0 && rc < size); > pos += rc; > size -= rc; > } > if (req->vclock != NULL) { > rc = snprintf(pos, size, ", vclock: %s", > vclock_to_string(req->vclock)); > - assert(rc >= 0); > + assert(rc >= 0 && rc < size); > pos += rc; > size -= rc; > } > rc = snprintf(pos, size, "}"); > - assert(rc >= 0); > + assert(rc >= 0 && rc < size); > pos += rc; > return tt_cstr(buf, pos - buf); > } -- Serge Petrenko ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Tarantool-patches] [PATCH v2 2/2] raft: decode even invalid states of raft 2020-10-29 8:37 [Tarantool-patches] [PATCH v2 0/2] raft: a few fixes for raft state symbolics Cyrill Gorcunov 2020-10-29 8:37 ` [Tarantool-patches] [PATCH v2 1/2] raft: raft_request_to_string -- don't hardcode size Cyrill Gorcunov @ 2020-10-29 8:37 ` Cyrill Gorcunov 2020-10-29 9:37 ` [Tarantool-patches] [PATCH v2 0/2] raft: a few fixes for raft state symbolics Cyrill Gorcunov 2020-11-02 22:02 ` Vladislav Shpilevoy 3 siblings, 0 replies; 6+ messages in thread From: Cyrill Gorcunov @ 2020-10-29 8:37 UTC (permalink / raw) To: tml; +Cc: Vladislav Shpilevoy We should never trust the request data it can carry anything, thus lets make sure we're not decoding some trash into a string. Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> --- src/box/lua/info.c | 2 +- src/box/raft.c | 29 +++++++++++++++++++++-------- src/box/raft.h | 6 +++++- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/box/lua/info.c b/src/box/lua/info.c index cac3fd475..92d48c96c 100644 --- a/src/box/lua/info.c +++ b/src/box/lua/info.c @@ -582,7 +582,7 @@ static int lbox_info_election(struct lua_State *L) { lua_createtable(L, 0, 4); - lua_pushstring(L, raft_state_strs[raft.state]); + lua_pushstring(L, raft_state_str(raft.state)); lua_setfield(L, -2, "state"); luaL_pushuint64(L, raft.volatile_term); lua_setfield(L, -2, "term"); diff --git a/src/box/raft.c b/src/box/raft.c index 7c546de8c..e1e60ce94 100644 --- a/src/box/raft.c +++ b/src/box/raft.c @@ -44,13 +44,6 @@ */ #define RAFT_RANDOM_ELECTION_FACTOR 0.1 -const char *raft_state_strs[] = { - NULL, - "follower", - "candidate", - "leader", -}; - /** Raft state of this instance. */ struct raft raft = { .leader = 0, @@ -70,6 +63,26 @@ struct raft raft = { .election_timeout = 5, }; +/** + * When decoding we should never trust that there is + * a valid data incomes. + */ +const char * +raft_state_str(uint32_t state) +{ + static const char *str[] = { + [0] = "invalid (0)", + [RAFT_STATE_FOLLOWER] = "follower", + [RAFT_STATE_CANDIDATE] = "candidate", + [RAFT_STATE_LEADER] = "leader", + }; + + if (state < lengthof(str)) + return str[state]; + + return "invalid (x)"; +}; + /** * Check if Raft is completely synced with disk. Meaning all its critical values * are in WAL. Only in that state the node can become a leader or a candidate. @@ -291,7 +304,7 @@ raft_request_to_string(const struct raft_request *req) } if (req->state != 0) { rc = snprintf(pos, size, ", state: %s", - raft_state_strs[req->state]); + raft_state_str(req->state)); assert(rc >= 0 && rc < size); pos += rc; size -= rc; diff --git a/src/box/raft.h b/src/box/raft.h index 82d5aa442..8293d7410 100644 --- a/src/box/raft.h +++ b/src/box/raft.h @@ -87,7 +87,11 @@ enum raft_state { RAFT_STATE_LEADER = 3, }; -extern const char *raft_state_strs[]; +/** + * Decode raft state into string representation. + */ +const char * +raft_state_str(uint32_t state); struct raft { /** Instance ID of leader of the current term. */ -- 2.26.2 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 0/2] raft: a few fixes for raft state symbolics 2020-10-29 8:37 [Tarantool-patches] [PATCH v2 0/2] raft: a few fixes for raft state symbolics Cyrill Gorcunov 2020-10-29 8:37 ` [Tarantool-patches] [PATCH v2 1/2] raft: raft_request_to_string -- don't hardcode size Cyrill Gorcunov 2020-10-29 8:37 ` [Tarantool-patches] [PATCH v2 2/2] raft: decode even invalid states of raft Cyrill Gorcunov @ 2020-10-29 9:37 ` Cyrill Gorcunov 2020-11-02 22:02 ` Vladislav Shpilevoy 3 siblings, 0 replies; 6+ messages in thread From: Cyrill Gorcunov @ 2020-10-29 9:37 UTC (permalink / raw) To: tml; +Cc: Vladislav Shpilevoy On Thu, Oct 29, 2020 at 11:37:05AM +0300, Cyrill Gorcunov wrote: > Just to make raft state symbolic representation being safe for > arbitrary data since we use it for debug purposes as well. > Forgot to pin the branch, gorcunov/raft-fixes-2 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 0/2] raft: a few fixes for raft state symbolics 2020-10-29 8:37 [Tarantool-patches] [PATCH v2 0/2] raft: a few fixes for raft state symbolics Cyrill Gorcunov ` (2 preceding siblings ...) 2020-10-29 9:37 ` [Tarantool-patches] [PATCH v2 0/2] raft: a few fixes for raft state symbolics Cyrill Gorcunov @ 2020-11-02 22:02 ` Vladislav Shpilevoy 3 siblings, 0 replies; 6+ messages in thread From: Vladislav Shpilevoy @ 2020-11-02 22:02 UTC (permalink / raw) To: Cyrill Gorcunov, tml Hi! Thanks for the patch! Pushed to master and 2.6. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-11-02 22:02 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-10-29 8:37 [Tarantool-patches] [PATCH v2 0/2] raft: a few fixes for raft state symbolics Cyrill Gorcunov 2020-10-29 8:37 ` [Tarantool-patches] [PATCH v2 1/2] raft: raft_request_to_string -- don't hardcode size Cyrill Gorcunov 2020-10-30 7:21 ` Serge Petrenko 2020-10-29 8:37 ` [Tarantool-patches] [PATCH v2 2/2] raft: decode even invalid states of raft Cyrill Gorcunov 2020-10-29 9:37 ` [Tarantool-patches] [PATCH v2 0/2] raft: a few fixes for raft state symbolics Cyrill Gorcunov 2020-11-02 22:02 ` Vladislav Shpilevoy
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox