[CONJ-1313] Race condition in HaMode#getAvailableHostInOrder can cause NPE (original) (raw)

A race condition can occur when multiple threads access the denyList concurrently.

java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because the return value of "java.util.concurrent.ConcurrentMap.get(Object)" is null at org.mariadb.jdbc.export.HaMode.getAvailableHostInOrder(HaMode.java:118) at org.mariadb.jdbc.export.HaMode$2.getAvailableHost(HaMode.java:31) at org.mariadb.jdbc.client.impl.MultiPrimaryClient.tryConnectToAvailableHost(MultiPrimaryClient.java:116) at org.mariadb.jdbc.client.impl.MultiPrimaryClient.connectHost(MultiPrimaryClient.java:90) at org.mariadb.jdbc.client.impl.MultiPrimaryClient.(MultiPrimaryClient.java:71) at org.mariadb.jdbc.Driver.connect(Driver.java:86) at org.mariadb.jdbc.Driver.connect(Driver.java:104) at org.mariadb.jdbc.Driver.connect(Driver.java:29) at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:681) at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:190)

This sequence is not atomic:
1. containsKey(hostAddress)
2. denyList.get(hostAddress)
Another thread can remove that key between those two calls, so get(...) returns null, and then < System.currentTimeMillis() forces unboxing to long, causing this NPE.