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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user