diff --git a/CHANGES.txt b/CHANGES.txt index 186a8d3497..81fb544c64 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -17,6 +17,7 @@ Merged from 2.2: * Fix leak errors and execution rejected exceptions when draining (CASSANDRA-12457) * Fix merkle tree depth calculation (CASSANDRA-12580) * Make Collections deserialization more robust (CASSANDRA-12618) + * Better handle invalid system roles table (CASSANDRA-12700) * Fix exceptions when enabling gossip on nodes that haven't joined the ring (CASSANDRA-12253) * Fix authentication problem when invoking cqlsh copy from a SOURCE command (CASSANDRA-12642) * Decrement pending range calculator jobs counter in finally block diff --git a/src/java/org/apache/cassandra/auth/CassandraRoleManager.java b/src/java/org/apache/cassandra/auth/CassandraRoleManager.java index b34b64803d..5e3b92df8c 100644 --- a/src/java/org/apache/cassandra/auth/CassandraRoleManager.java +++ b/src/java/org/apache/cassandra/auth/CassandraRoleManager.java @@ -81,11 +81,23 @@ public class CassandraRoleManager implements IRoleManager { public Role apply(UntypedResultSet.Row row) { - return new Role(row.getString("role"), - row.getBoolean("is_superuser"), - row.getBoolean("can_login"), - row.has("member_of") ? row.getSet("member_of", UTF8Type.instance) - : Collections.emptySet()); + try + { + return new Role(row.getString("role"), + row.getBoolean("is_superuser"), + row.getBoolean("can_login"), + row.has("member_of") ? row.getSet("member_of", UTF8Type.instance) + : Collections.emptySet()); + } + // Failing to deserialize a boolean in is_superuser or can_login will throw an NPE + catch (NullPointerException e) + { + logger.warn("An invalid value has been detected in the {} table for role {}. If you are " + + "unable to login, you may need to disable authentication and confirm " + + "that values in that table are accurate", AuthKeyspace.ROLES, row.getString("role")); + throw new RuntimeException(String.format("Invalid metadata has been detected for role %s", row.getString("role")), e); + } + } }; diff --git a/src/java/org/apache/cassandra/serializers/BooleanSerializer.java b/src/java/org/apache/cassandra/serializers/BooleanSerializer.java index dffecd6502..0d6580ea7f 100644 --- a/src/java/org/apache/cassandra/serializers/BooleanSerializer.java +++ b/src/java/org/apache/cassandra/serializers/BooleanSerializer.java @@ -30,7 +30,7 @@ public class BooleanSerializer implements TypeSerializer public Boolean deserialize(ByteBuffer bytes) { - if (bytes.remaining() == 0) + if (bytes == null || bytes.remaining() == 0) return null; byte value = bytes.get(bytes.position());