From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: Cyrill Gorcunov <gorcunov@gmail.com>, Serge Petrenko <sergepetrenko@tarantool.org> Cc: tml <tarantool-patches@dev.tarantool.org> Subject: Re: [Tarantool-patches] [PATCH 2/2] raft: decode even invalid states of raft Date: Tue, 27 Oct 2020 23:18:18 +0100 [thread overview] Message-ID: <02839650-d213-98d2-1cbf-7fb95d52102c@tarantool.org> (raw) In-Reply-To: <20201014142617.235813-3-gorcunov@gmail.com> Hi! Thanks for the patch! See 2 comments below. On 14.10.2020 16:26, Cyrill Gorcunov wrote: > 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 | 11 ++++++++++- > 3 files changed, 32 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)); 1. Raft.state is always valid. It can't be NONE. If a request with a bad state is received, it just should be rejected with a protocol error. > 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 9de77b0ec..44a76154f 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[] = { > + [RAFT_STATE_NONE] = "none", > + [RAFT_STATE_FOLLOWER] = "follower", > + [RAFT_STATE_CANDIDATE] = "candidate", > + [RAFT_STATE_LEADER] = "leader", > + }; > + > + if (state < lengthof(str)) > + return str[state]; > + > + return "unknown"; > +}; > + > /** > * 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. > @@ -284,7 +297,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)); 2. By doing so you didn't fix the actual issue - the state is still applied in raft_process_msg(). Moreover, in debug build it will crash, because there is a switch-case by the received state, which does panic() on an unknown state. The invalid state should be filtered out in the beginning of raft_process_msg(), like all the other fields checked there for sanity. State is checked here, but only for not being 0. Need to check for the max value too, that is it.
next prev parent reply other threads:[~2020-10-27 22:18 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-10-14 14:26 [Tarantool-patches] [PATCH 0/2] raft: a few fixes Cyrill Gorcunov 2020-10-14 14:26 ` [Tarantool-patches] [PATCH 1/2] raft: raft_request_to_string -- don't hardcode size Cyrill Gorcunov 2020-10-14 14:26 ` [Tarantool-patches] [PATCH 2/2] raft: decode even invalid states of raft Cyrill Gorcunov 2020-10-15 9:43 ` Serge Petrenko 2020-10-15 9:46 ` Cyrill Gorcunov 2020-10-27 22:18 ` Vladislav Shpilevoy [this message] 2020-10-27 22:36 ` Cyrill Gorcunov 2020-10-15 8:44 ` [Tarantool-patches] [PATCH 0/2] raft: a few fixes Cyrill Gorcunov
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=02839650-d213-98d2-1cbf-7fb95d52102c@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=gorcunov@gmail.com \ --cc=sergepetrenko@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH 2/2] raft: decode even invalid states of raft' \ /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