From 3004885e8b41e1db0a9fc9116d11bd0e897a44d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B8=D0=BB=D1=8F=D0=BD=20=D0=9F=D0=B0=D0=BB=D0=B0?= =?UTF-8?q?=D1=83=D0=B7=D0=BE=D0=B2?= Date: Sat, 29 Nov 2025 17:01:19 +0200 Subject: [PATCH] SerialImp.c:getRegistryString() - make thread-safe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CommPortIdentifier.java:getPortIdentifiers() calls `(new RXTXCommDriver()).initialize()` → RXTXCommDriver.java:initialize() → registerKnownPorts(CommPortIdentifier.PORT_SERIAL) → SerialImp.c:RXTXCommDriver(registerKnownPorts) → getRegistryString() → and it returns its value in a static allocated string (`static char resultStr[256]`). If two threads call at the same time CommPortIdentifier.java:getPortIdentifiers(), both threads will write at the same time in that `static char resultStr[256]`. Likewise, when two threads at the same time call RXTXCommDriver.isPortPrefixValid(), there will also be multithreading problem, the only fact which saves the situation is that this is not called from anywhere. --- src/main/c/src/SerialImp.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/c/src/SerialImp.c b/src/main/c/src/SerialImp.c index 3b7c5e25..3a0319ce 100644 --- a/src/main/c/src/SerialImp.c +++ b/src/main/c/src/SerialImp.c @@ -4650,7 +4650,7 @@ createSerialIterator(io_iterator_t *serialIterator) char * getRegistryString(io_object_t sObj, char *propName) { - static char resultStr[256]; + char* resultStr = malloc(256); CFTypeRef nameCFstring; resultStr[0] = 0; nameCFstring = IORegistryEntryCreateCFProperty(sObj, @@ -4658,7 +4658,7 @@ getRegistryString(io_object_t sObj, char *propName) kCFAllocatorDefault, 0); if (nameCFstring) { - CFStringGetCString(nameCFstring, resultStr, sizeof(resultStr), kCFStringEncodingASCII); + CFStringGetCString(nameCFstring, resultStr, 256, kCFStringEncodingASCII); CFRelease(nameCFstring); } return resultStr; @@ -4702,12 +4702,15 @@ registerKnownSerialPorts(JNIEnv *env, jobject jobj, jint portType) /* dima */ { /* begin dima */ jstring tempJstring; - tempJstring = (*env)->NewStringUTF(env,getRegistryString(theObject, kIODialinDeviceKey)); + char* temp = getRegistryString(theObject, kIODialinDeviceKey); + tempJstring = (*env)->NewStringUTF(env,temp); + free(temp); (*env)->CallStaticVoidMethod(env, cls, mid,tempJstring,portType,jobj);/* dima */ (*env)->DeleteLocalRef(env,tempJstring); numPorts++; - - tempJstring = (*env)->NewStringUTF(env,getRegistryString(theObject, kIOCalloutDeviceKey)); + temp = getRegistryString(theObject, kIOCalloutDeviceKey); + tempJstring = (*env)->NewStringUTF(env,temp); + free(temp); (*env)->CallStaticVoidMethod(env, cls, mid,tempJstring,portType,jobj);/* dima */ (*env)->DeleteLocalRef(env,tempJstring); numPorts++; @@ -4775,7 +4778,7 @@ JNIEXPORT jboolean JNICALL RXTXCommDriver(isPortPrefixValid)(JNIEnv *env, jobject jobj, jstring tty_name) { jboolean result; - static struct stat mystat; + struct stat mystat; char teststring[256]; int fd,i; const char *name = (*env)->GetStringUTFChars(env, tty_name, 0);