android: native - hold charon_mutex while reading routing engine stats
getRoutingStats/getDeadDirectTargets are polled from the UI once a second; a concurrent disconnect frees the engine under charon_mutex, so reading it without the lock was a use-after-free. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5e38fc2f76
commit
793ca1b410
1 file changed
+11
-2
@@ -1325,16 +1325,21 @@ JNI_METHOD(CharonVpnService, setUserspaceRoutingData, void,
|
||||
*/
|
||||
JNI_METHOD(CharonVpnService, getRoutingStats, jlongArray)
|
||||
{
|
||||
direct_engine_t *engine = direct_engine_get();
|
||||
direct_engine_t *engine;
|
||||
direct_stats_t s = {};
|
||||
jlong v[22];
|
||||
jlongArray result;
|
||||
|
||||
memset(&s, 0, sizeof(s));
|
||||
/* polled from the UI: a concurrent disconnect frees the engine under
|
||||
* charon_mutex, so the pointer may only be used while holding it */
|
||||
pthread_mutex_lock(&charon_mutex);
|
||||
engine = direct_engine_get();
|
||||
if (engine)
|
||||
{
|
||||
engine->get_stats(engine, &s);
|
||||
}
|
||||
pthread_mutex_unlock(&charon_mutex);
|
||||
v[0] = (jlong)s.tunnel_pkts;
|
||||
v[1] = (jlong)s.tunnel_bytes;
|
||||
v[2] = (jlong)s.direct_pkts;
|
||||
@@ -1370,7 +1375,7 @@ JNI_METHOD(CharonVpnService, getRoutingStats, jlongArray)
|
||||
*/
|
||||
JNI_METHOD(CharonVpnService, getDeadDirectTargets, jobjectArray)
|
||||
{
|
||||
direct_engine_t *engine = direct_engine_get();
|
||||
direct_engine_t *engine;
|
||||
direct_dead_target_t t[DIRECT_DEAD_MAX];
|
||||
jobjectArray result;
|
||||
jclass cls;
|
||||
@@ -1379,10 +1384,14 @@ JNI_METHOD(CharonVpnService, getDeadDirectTargets, jobjectArray)
|
||||
/* stack snapshot: zero it so no field can ever leak garbage */
|
||||
memset(t, 0, sizeof(t));
|
||||
|
||||
/* same race against a concurrent disconnect as getRoutingStats() */
|
||||
pthread_mutex_lock(&charon_mutex);
|
||||
engine = direct_engine_get();
|
||||
if (engine)
|
||||
{
|
||||
n = engine->get_dead_targets(engine, t, DIRECT_DEAD_MAX);
|
||||
}
|
||||
pthread_mutex_unlock(&charon_mutex);
|
||||
cls = (*env)->FindClass(env, "java/lang/String");
|
||||
if (!cls)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user