cql3/query_processor: Validate presence of statement values timeously

We need to validate before calling query_options::prepare() whether
the set of prepared statement values sent in the query matches the
amount of names we need to bind, otherwise we risk an out-of-bounds
access if the client also specified names together with the values.

Refs #3688

Signed-off-by: Duarte Nunes <duarte@scylladb.com>
Message-Id: <20180814225607.14215-1-duarte@scylladb.com>
This commit is contained in:
Duarte Nunes
2018-08-14 23:56:07 +01:00
committed by Paweł Dziepak
parent d734d316a6
commit 805ce6e019
2 changed files with 4 additions and 2 deletions

View File

@@ -273,11 +273,11 @@ query_processor::process(const sstring_view& query_string, service::query_state&
log.trace("process: \"{}\"", query_string);
tracing::trace(query_state.get_trace_state(), "Parsing a statement");
auto p = get_statement(query_string, query_state.get_client_state());
options.prepare(p->bound_names);
auto cql_statement = p->statement;
if (cql_statement->get_bound_terms() != options.get_values_count()) {
throw exceptions::invalid_request_exception("Invalid amount of bind variables");
}
options.prepare(p->bound_names);
warn(unimplemented::cause::METRICS);
#if 0

View File

@@ -853,7 +853,6 @@ future<response_type> cql_server::connection::process_execute(uint16_t stream, r
}
auto& options = *q_state->options;
auto skip_metadata = options.skip_metadata();
options.prepare(prepared->bound_names);
tracing::set_page_size(client_state.get_trace_state(), options.get_page_size());
tracing::set_consistency_level(client_state.get_trace_state(), options.get_consistency());
@@ -870,6 +869,9 @@ future<response_type> cql_server::connection::process_execute(uint16_t stream, r
tracing::trace(query_state.get_trace_state(), "Invalid amount of bind variables: expected {:d} received {:d}", stmt->get_bound_terms(), options.get_values_count());
throw exceptions::invalid_request_exception("Invalid amount of bind variables");
}
options.prepare(prepared->bound_names);
tracing::trace(query_state.get_trace_state(), "Processing a statement");
return _server._query_processor.local().process_statement_prepared(std::move(prepared), std::move(cache_key), query_state, options, needs_authorization).then([this, stream, &query_state, skip_metadata] (auto msg) {
tracing::trace(query_state.get_trace_state(), "Done processing - preparing a result");