Sam Veloso created CASSCPP-17:
---------------------------------
Summary: Crash in update_indexes when adding an index for a table
missing from schema metadata
Key: CASSCPP-17
URL: https://issues.apache.org/jira/browse/CASSCPP-17
Project: Apache Cassandra C/C++ driver
Issue Type: Bug
Reporter: Sam Veloso
During control-connection schema refresh (Cluster::on_reconnect → update_schema
→ update_indexes), the driver can dereference a null TableMetadata::Ptr and
abort. This happens when system_schema.indexes contains two or more index rows
for a table that is not present in the in-memory table metadata.
Observed with cpp-driver 2.17.1. The same unguarded add_index() is still
present on master (src/metadata.cpp, Metadata::InternalData::update_indexes).
*Possible root cause*
update_indexes() already skips a missing table on the *first* index row, but it
leaves table null while table_name is set to that missing table. Later index
rows for the same table skip the lookup and call add_index() unconditionally:
{code:cpp}
if (table_name != temp_table_name) {
table_name = temp_table_name;
table = keyspace->get_table(table_name);
if (!table) continue;
table->clear_indexes();
}
table->add_index(IndexMetadata::from_row(index_name, buffer, row));
{code}
*Sequence:*
# First index row for missing table T: get_table() fails, \{{if (!table)
continue}}, table stays null, table_name is T.
# Next index row for the same T: \{{table_name != temp_table_name}} is false,
so the lookup is skipped.
# \{{table->add_index(...)}} runs on a null TableMetadata::Ptr.
A single leftover index row for a missing table does not crash (the continue
already skips it). Two or more index rows for that table do.
This is inconsistent with the sibling helpers in the same file:
update_columns() and update_legacy_indexes() wrap the mutation in \{{if
(table)}}.
The window is realistic whenever tables and indexes are queried as separate
result sets during reconnect, especially if a table was dropped (or not yet in
metadata) while system_schema.indexes still has multiple indexes for it.
*Expected*
Index rows whose table is not in metadata should be skipped for every row, not
only the first. The driver should not crash.
*Possible fix*
Guard add_index() the same way update_legacy_indexes() does:
{code:cpp}
if (table) {
table->add_index(IndexMetadata::from_row(index_name, buffer, row));
}
{code}
*Environment*
* cpp-driver 2.17.1 (also current master)
* Cassandra 3.x/4.x-style system_schema.indexes (update_indexes, not the legacy
column-index path)
* Trigger: control connection reconnect / schema metadata refresh while indexes
exist for a table the driver does not have
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]