Skip to content

Commit bf59914

Browse files
committed
Fix JNI local reference use-after-free in getConnectivityManagerIp
connManager's local reference was deleted right after getActiveNetwork() but then reused for getLinkProperties(), corrupting the JNI local reference table (observed as a SIGABRT: "jobject is an invalid local reference... popped reference at index 15 in a table of size 12", crashing inside QMdnsEngine::ProviderPrivate::publish() -> getIP()). Fix by only deleting local refs after their last use, and wrap the whole function in PushLocalFrame/PopLocalFrame so it doesn't depend on the calling thread's default local reference capacity.
1 parent a91d032 commit bf59914

1 file changed

Lines changed: 12 additions & 14 deletions

File tree

src/localipaddress.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,20 @@ int getIpAddress(JNIEnv *env, jobject wifiInfoObj) {
103103
QString getConnectivityManagerIp(JNIEnv *env, jobject jCtxObj) {
104104
qDebug() << "getConnectivityManagerIp....";
105105

106+
// Reserve enough local reference slots for this whole call, regardless of
107+
// the caller thread's default JNI local reference frame capacity.
108+
if (env->PushLocalFrame(32) < 0) {
109+
return QString();
110+
}
111+
106112
jclass jCtxClz = env->FindClass("android/content/Context");
107113
jfieldID fidConnService = env->GetStaticFieldID(jCtxClz, "CONNECTIVITY_SERVICE", "Ljava/lang/String;");
108114
jstring jstrConnService = (jstring)env->GetStaticObjectField(jCtxClz, fidConnService);
109115
jmethodID midGetSystemService =
110116
env->GetMethodID(jCtxClz, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
111117
jobject connManager = env->CallObjectMethod(jCtxObj, midGetSystemService, jstrConnService);
112-
env->DeleteLocalRef(jCtxClz);
113-
env->DeleteLocalRef(jstrConnService);
114118
if (connManager == NULL) {
119+
env->PopLocalFrame(NULL);
115120
return QString();
116121
}
117122

@@ -121,32 +126,28 @@ QString getConnectivityManagerIp(JNIEnv *env, jobject jCtxObj) {
121126
jmethodID midGetActiveNetwork = env->GetMethodID(connManagerClz, "getActiveNetwork", "()Landroid/net/Network;");
122127
if (midGetActiveNetwork == NULL) {
123128
env->ExceptionClear();
124-
env->DeleteLocalRef(connManagerClz);
125-
env->DeleteLocalRef(connManager);
129+
env->PopLocalFrame(NULL);
126130
return QString();
127131
}
128132
jobject network = env->CallObjectMethod(connManager, midGetActiveNetwork);
129-
env->DeleteLocalRef(connManager);
130133
if (network == NULL) {
131-
env->DeleteLocalRef(connManagerClz);
134+
env->PopLocalFrame(NULL);
132135
return QString();
133136
}
134137

135138
jmethodID midGetLinkProperties = env->GetMethodID(
136139
connManagerClz, "getLinkProperties", "(Landroid/net/Network;)Landroid/net/LinkProperties;");
137140
jobject linkProperties = env->CallObjectMethod(connManager, midGetLinkProperties, network);
138-
env->DeleteLocalRef(connManagerClz);
139-
env->DeleteLocalRef(network);
140141
if (linkProperties == NULL) {
142+
env->PopLocalFrame(NULL);
141143
return QString();
142144
}
143145

144146
jclass linkPropertiesClz = env->GetObjectClass(linkProperties);
145147
jmethodID midGetLinkAddresses = env->GetMethodID(linkPropertiesClz, "getLinkAddresses", "()Ljava/util/List;");
146148
jobject linkAddresses = env->CallObjectMethod(linkProperties, midGetLinkAddresses);
147-
env->DeleteLocalRef(linkPropertiesClz);
148-
env->DeleteLocalRef(linkProperties);
149149
if (linkAddresses == NULL) {
150+
env->PopLocalFrame(NULL);
150151
return QString();
151152
}
152153

@@ -193,10 +194,7 @@ QString getConnectivityManagerIp(JNIEnv *env, jobject jCtxObj) {
193194
}
194195
}
195196

196-
env->DeleteLocalRef(linkAddressClz);
197-
env->DeleteLocalRef(inet4Clz);
198-
env->DeleteLocalRef(listClz);
199-
env->DeleteLocalRef(linkAddresses);
197+
env->PopLocalFrame(NULL);
200198
return result;
201199
}
202200
#endif

0 commit comments

Comments
 (0)