提交 a83ee105 编写于 作者: R robm

8133249: Occasional SIGSEGV: non thread-safe use of strerr in get LastErrorString

Reviewed-by: coffeys, igerasim
上级 72d6d0ac
...@@ -205,6 +205,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \ ...@@ -205,6 +205,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \
-framework Foundation \ -framework Foundation \
-framework Security -framework SystemConfiguration, \ -framework Security -framework SystemConfiguration, \
LDFLAGS_SUFFIX_windows := -export:winFileHandleOpen -export:handleLseek \ LDFLAGS_SUFFIX_windows := -export:winFileHandleOpen -export:handleLseek \
-export:getErrorString \
jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \ jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \
shell32.lib delayimp.lib -DELAYLOAD:shell32.dll \ shell32.lib delayimp.lib -DELAYLOAD:shell32.dll \
advapi32.lib version.lib, \ advapi32.lib version.lib, \
......
...@@ -284,6 +284,8 @@ SUNWprivate_1.1 { ...@@ -284,6 +284,8 @@ SUNWprivate_1.1 {
# ZipFile.c needs this one # ZipFile.c needs this one
throwFileNotFoundException; throwFileNotFoundException;
# zip_util.c needs this
getErrorString;
# Java_sun_misc_VM_getState; threads.c # Java_sun_misc_VM_getState; threads.c
# Java_sun_misc_VM_threadsSuspended; threads.c # Java_sun_misc_VM_threadsSuspended; threads.c
......
...@@ -391,6 +391,7 @@ void* getProcessHandle(); ...@@ -391,6 +391,7 @@ void* getProcessHandle();
void buildJniFunctionName(const char *sym, const char *cname, void buildJniFunctionName(const char *sym, const char *cname,
char *jniEntryName); char *jniEntryName);
extern int getErrorString(int err, char *buf, size_t len);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif /* __cplusplus */ #endif /* __cplusplus */
......
...@@ -1449,6 +1449,7 @@ jboolean JNICALL ...@@ -1449,6 +1449,7 @@ jboolean JNICALL
ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname) ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
{ {
char *msg; char *msg;
char tmpbuf[1024];
strcpy(entryname, entry->name); strcpy(entryname, entry->name);
if (entry->csize == 0) { if (entry->csize == 0) {
...@@ -1467,8 +1468,11 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname) ...@@ -1467,8 +1468,11 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
msg = zip->msg; msg = zip->msg;
ZIP_Unlock(zip); ZIP_Unlock(zip);
if (n == -1) { if (n == -1) {
jio_fprintf(stderr, "%s: %s\n", zip->name, if (msg == 0) {
msg != 0 ? msg : strerror(errno)); getErrorString(errno, tmpbuf, sizeof(tmpbuf));
msg = tmpbuf;
}
jio_fprintf(stderr, "%s: %s\n", zip->name, msg);
return JNI_FALSE; return JNI_FALSE;
} }
buf += n; buf += n;
...@@ -1481,8 +1485,11 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname) ...@@ -1481,8 +1485,11 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
if ((msg == NULL) || (*msg == 0)) { if ((msg == NULL) || (*msg == 0)) {
msg = zip->msg; msg = zip->msg;
} }
jio_fprintf(stderr, "%s: %s\n", zip->name, if (msg == 0) {
msg != 0 ? msg : strerror(errno)); getErrorString(errno, tmpbuf, sizeof(tmpbuf));
msg = tmpbuf;
}
jio_fprintf(stderr, "%s: %s\n", zip->name, msg);
return JNI_FALSE; return JNI_FALSE;
} }
} }
......
...@@ -37,6 +37,13 @@ char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) ...@@ -37,6 +37,13 @@ char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
return NULL; return NULL;
} }
#if defined(LINUX) && (defined(_GNU_SOURCE) || \
(defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE < 200112L \
&& defined(_XOPEN_SOURCE) && _XOPEN_SOURCE < 600))
extern int __xpg_strerror_r(int, char *, size_t);
#define strerror_r(a, b, c) __xpg_strerror_r((a), (b), (c))
#endif
void* getProcessHandle() { void* getProcessHandle() {
static void *procHandle = NULL; static void *procHandle = NULL;
if (procHandle != NULL) { if (procHandle != NULL) {
...@@ -59,3 +66,9 @@ void buildJniFunctionName(const char *sym, const char *cname, ...@@ -59,3 +66,9 @@ void buildJniFunctionName(const char *sym, const char *cname,
} }
} }
int
getErrorString(int err, char *buf, size_t len)
{
if (err == 0 || len < 1) return 0;
return strerror_r(err, buf, len);
}
...@@ -216,13 +216,6 @@ size_t ...@@ -216,13 +216,6 @@ size_t
getLastErrorString(char *buf, size_t len) getLastErrorString(char *buf, size_t len)
{ {
if (errno == 0 || len < 1) return 0; if (errno == 0 || len < 1) return 0;
getErrorString(errno, buf, len);
const char *err = strerror(errno); return strlen(buf);
size_t n = strlen(err);
if (n >= len)
n = len - 1;
strncpy(buf, err, n);
buf[n] = '\0';
return n;
} }
...@@ -292,12 +292,13 @@ throwIOException(JNIEnv *env, int errnum, const char *defaultDetail) ...@@ -292,12 +292,13 @@ throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
static const char * const format = "error=%d, %s"; static const char * const format = "error=%d, %s";
const char *detail = defaultDetail; const char *detail = defaultDetail;
char *errmsg; char *errmsg;
char tmpbuf[1024];
jstring s; jstring s;
if (errnum != 0) { if (errnum != 0) {
const char *s = strerror(errnum); int ret = getErrorString(errnum, tmpbuf, sizeof(tmpbuf));
if (strcmp(s, "Unknown error") != 0) if (ret != EINVAL)
detail = s; detail = tmpbuf;
} }
/* ASCII Decimal representation uses 2.4 times as many bits as binary. */ /* ASCII Decimal representation uses 2.4 times as many bits as binary. */
errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum)); errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum));
......
...@@ -954,6 +954,7 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, ...@@ -954,6 +954,7 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
jobject this) { jobject this) {
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID); jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
int arg, fd, t = 1; int arg, fd, t = 1;
char tmpbuf[1024];
#ifdef AF_INET6 #ifdef AF_INET6
int domain = ipv6_available() ? AF_INET6 : AF_INET; int domain = ipv6_available() ? AF_INET6 : AF_INET;
#else #else
...@@ -989,14 +990,14 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, ...@@ -989,14 +990,14 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
arg = 65507; arg = 65507;
if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_SNDBUF, if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_SNDBUF,
(char *)&arg, sizeof(arg)) < 0) { (char *)&arg, sizeof(arg)) < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", getErrorString(errno, tmpbuf, sizeof(tmpbuf));
strerror(errno)); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
return; return;
} }
if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_RCVBUF, if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_RCVBUF,
(char *)&arg, sizeof(arg)) < 0) { (char *)&arg, sizeof(arg)) < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", getErrorString(errno, tmpbuf, sizeof(tmpbuf));
strerror(errno)); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
return; return;
} }
#endif /* __APPLE__ */ #endif /* __APPLE__ */
...@@ -1007,9 +1008,10 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, ...@@ -1007,9 +1008,10 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
arg = 0; arg = 0;
int level = (domain == AF_INET6) ? IPPROTO_IPV6 : IPPROTO_IP; int level = (domain == AF_INET6) ? IPPROTO_IPV6 : IPPROTO_IP;
if ((setsockopt(fd, level, IP_MULTICAST_ALL, (char*)&arg, sizeof(arg)) < 0) && if ((setsockopt(fd, level, IP_MULTICAST_ALL, (char*)&arg, sizeof(arg)) < 0) &&
(errno != ENOPROTOOPT)) { (errno != ENOPROTOOPT))
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", {
strerror(errno)); getErrorString(errno, tmpbuf, sizeof(tmpbuf));
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
close(fd); close(fd);
return; return;
} }
......
...@@ -308,21 +308,15 @@ Java_sun_nio_fs_UnixNativeDispatcher_getcwd(JNIEnv* env, jclass this) { ...@@ -308,21 +308,15 @@ Java_sun_nio_fs_UnixNativeDispatcher_getcwd(JNIEnv* env, jclass this) {
JNIEXPORT jbyteArray JNIEXPORT jbyteArray
Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint error) Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint error)
{ {
char* msg; char tmpbuf[1024];
jsize len; jsize len;
jbyteArray bytes; jbyteArray bytes;
#ifdef _AIX getErrorString((int)errno, tmpbuf, sizeof(tmpbuf));
/* strerror() is not thread-safe on AIX so we have to use strerror_r() */ len = strlen(tmpbuf);
char buffer[256];
msg = (strerror_r((int)error, buffer, 256) == 0) ? buffer : "Error while calling strerror_r";
#else
msg = strerror((int)error);
#endif
len = strlen(msg);
bytes = (*env)->NewByteArray(env, len); bytes = (*env)->NewByteArray(env, len);
if (bytes != NULL) { if (bytes != NULL) {
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg); (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)tmpbuf);
} }
return bytes; return bytes;
} }
......
...@@ -142,6 +142,15 @@ void* getProcessHandle() { ...@@ -142,6 +142,15 @@ void* getProcessHandle() {
return (void*)GetModuleHandle(NULL); return (void*)GetModuleHandle(NULL);
} }
int
getErrorString(int err, char *buf, size_t len)
{
int ret = 0;
if (err == 0 || len < 1) return 0;
ret = strerror_s(buf, len, err);
return ret;
}
/* /*
* Windows symbols can be simple like JNI_OnLoad or __stdcall format * Windows symbols can be simple like JNI_OnLoad or __stdcall format
* like _JNI_OnLoad@8. We need to handle both. * like _JNI_OnLoad@8. We need to handle both.
......
...@@ -2239,8 +2239,11 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobj ...@@ -2239,8 +2239,11 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobj
optlen = sizeof(optval.i); optlen = sizeof(optval.i);
if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) { if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
char errmsg[255]; char tmpbuf[255];
sprintf(errmsg, "error getting socket option: %s\n", strerror(errno)); int size = 0;
char errmsg[255 + 31];
getErrorString(errno, tmpbuf, sizeof(tmpbuf));
sprintf(errmsg, "error getting socket option: %s", tmpbuf);
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", errmsg); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", errmsg);
return NULL; return NULL;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册