time_series_sstable_set::create_single_key_sstable_reader(): fix use-after-free

The optimal path of said method mistakenly captures `pos` (a local
variable) in its reader factory method and passes a temporary range
implicitly constructed from said `pos` as the range parameter to the
sstable reader. This will lead to the sstable reader using a dangling
range and will result in returning no result for queries. This patch
fixes this bug and adds a unit test to cover this code path.

Fixes #8138.

Signed-off-by: Botond Dénes <bdenes@scylladb.com>
Message-Id: <20210226143111.104591-2-bdenes@scylladb.com>
This commit is contained in:
Botond Dénes
2021-02-26 16:31:10 +02:00
committed by Avi Kivity
parent dd5a601aaa
commit 1d9b5911fe
2 changed files with 27 additions and 2 deletions

View File

@@ -790,8 +790,8 @@ time_series_sstable_set::create_single_key_sstable_reader(
return flat_mutation_reader_from_mutations(std::move(permit), {mutation(schema, *pos.key())}, slice, fwd_sm);
}
auto create_reader = [schema, permit, &pos, &slice, &pc, trace_state, fwd_sm] (sstable& sst) {
return sst.make_reader(schema, permit, pos, slice, pc, trace_state, fwd_sm);
auto create_reader = [schema, permit, &pr, &slice, &pc, trace_state, fwd_sm] (sstable& sst) {
return sst.make_reader(schema, permit, pr, slice, pc, trace_state, fwd_sm);
};
// We're going to pass this filter into min_position_reader_queue. The queue guarantees that

View File

@@ -4810,3 +4810,28 @@ SEASTAR_THREAD_TEST_CASE(test_twcs_non_optimal_query_path) {
e.execute_cql("SELECT * FROM tbl WHERE pk = 0 BYPASS CACHE").get();
}).get();
}
SEASTAR_THREAD_TEST_CASE(test_twcs_optimal_query_path) {
do_with_cql_env_thread([] (cql_test_env& e) {
auto now_nano = std::chrono::duration_cast<std::chrono::nanoseconds>(db_clock::now().time_since_epoch()).count();
e.execute_cql(
"CREATE TABLE tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck))"
" WITH compaction = {"
" 'compaction_window_size': '1',"
" 'compaction_window_unit': 'MINUTES',"
" 'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy'"
"}").get();
e.execute_cql("INSERT INTO tbl (pk, ck, v) VALUES (0, 0, 0)").get();
e.db().invoke_on_all([] (database& db) {
return db.flush_all_memtables();
}).get();
// Not really testing anything, just ensure that we execute the optimal
// sstable read path of TWCS tables too, allowing ASAN to shake out any memory
// related bugs.
assert_that(e.execute_cql("SELECT * FROM tbl WHERE pk = 0 BYPASS CACHE").get0())
.is_rows().with_size(1);
}).get();
}