Wed, 07 Nov 2012 17:53:02 -0500
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
Summary: dll_dir can contain multiple paths, need to parse them correctly when loading agents
Reviewed-by: dholmes, dlong
Contributed-by: bill.pittore@oracle.com
1.1 --- a/src/os/bsd/vm/os_bsd.cpp Mon Nov 05 19:33:44 2012 -0500 1.2 +++ b/src/os/bsd/vm/os_bsd.cpp Wed Nov 07 17:53:02 2012 -0500 1.3 @@ -1198,19 +1198,20 @@ 1.4 return os::stat(filename, &statbuf) == 0; 1.5 } 1.6 1.7 -void os::dll_build_name(char* buffer, size_t buflen, 1.8 +bool os::dll_build_name(char* buffer, size_t buflen, 1.9 const char* pname, const char* fname) { 1.10 + bool retval = false; 1.11 // Copied from libhpi 1.12 const size_t pnamelen = pname ? strlen(pname) : 0; 1.13 1.14 - // Quietly truncate on buffer overflow. Should be an error. 1.15 + // Return error on buffer overflow. 1.16 if (pnamelen + strlen(fname) + strlen(JNI_LIB_PREFIX) + strlen(JNI_LIB_SUFFIX) + 2 > buflen) { 1.17 - *buffer = '\0'; 1.18 - return; 1.19 + return retval; 1.20 } 1.21 1.22 if (pnamelen == 0) { 1.23 snprintf(buffer, buflen, JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, fname); 1.24 + retval = true; 1.25 } else if (strchr(pname, *os::path_separator()) != NULL) { 1.26 int n; 1.27 char** pelements = split_path(pname, &n); 1.28 @@ -1222,6 +1223,7 @@ 1.29 snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, 1.30 pelements[i], fname); 1.31 if (file_exists(buffer)) { 1.32 + retval = true; 1.33 break; 1.34 } 1.35 } 1.36 @@ -1236,7 +1238,9 @@ 1.37 } 1.38 } else { 1.39 snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname); 1.40 + retval = true; 1.41 } 1.42 + return retval; 1.43 } 1.44 1.45 const char* os::get_current_directory(char *buf, int buflen) {
2.1 --- a/src/os/linux/vm/os_linux.cpp Mon Nov 05 19:33:44 2012 -0500 2.2 +++ b/src/os/linux/vm/os_linux.cpp Wed Nov 07 17:53:02 2012 -0500 2.3 @@ -1650,19 +1650,20 @@ 2.4 return os::stat(filename, &statbuf) == 0; 2.5 } 2.6 2.7 -void os::dll_build_name(char* buffer, size_t buflen, 2.8 +bool os::dll_build_name(char* buffer, size_t buflen, 2.9 const char* pname, const char* fname) { 2.10 + bool retval = false; 2.11 // Copied from libhpi 2.12 const size_t pnamelen = pname ? strlen(pname) : 0; 2.13 2.14 - // Quietly truncate on buffer overflow. Should be an error. 2.15 + // Return error on buffer overflow. 2.16 if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { 2.17 - *buffer = '\0'; 2.18 - return; 2.19 + return retval; 2.20 } 2.21 2.22 if (pnamelen == 0) { 2.23 snprintf(buffer, buflen, "lib%s.so", fname); 2.24 + retval = true; 2.25 } else if (strchr(pname, *os::path_separator()) != NULL) { 2.26 int n; 2.27 char** pelements = split_path(pname, &n); 2.28 @@ -1673,6 +1674,7 @@ 2.29 } 2.30 snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname); 2.31 if (file_exists(buffer)) { 2.32 + retval = true; 2.33 break; 2.34 } 2.35 } 2.36 @@ -1687,7 +1689,9 @@ 2.37 } 2.38 } else { 2.39 snprintf(buffer, buflen, "%s/lib%s.so", pname, fname); 2.40 - } 2.41 + retval = true; 2.42 + } 2.43 + return retval; 2.44 } 2.45 2.46 const char* os::get_current_directory(char *buf, int buflen) {
3.1 --- a/src/os/solaris/vm/os_solaris.cpp Mon Nov 05 19:33:44 2012 -0500 3.2 +++ b/src/os/solaris/vm/os_solaris.cpp Wed Nov 07 17:53:02 2012 -0500 3.3 @@ -1894,18 +1894,19 @@ 3.4 return os::stat(filename, &statbuf) == 0; 3.5 } 3.6 3.7 -void os::dll_build_name(char* buffer, size_t buflen, 3.8 +bool os::dll_build_name(char* buffer, size_t buflen, 3.9 const char* pname, const char* fname) { 3.10 + bool retval = false; 3.11 const size_t pnamelen = pname ? strlen(pname) : 0; 3.12 3.13 - // Quietly truncate on buffer overflow. Should be an error. 3.14 + // Return error on buffer overflow. 3.15 if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { 3.16 - *buffer = '\0'; 3.17 - return; 3.18 + return retval; 3.19 } 3.20 3.21 if (pnamelen == 0) { 3.22 snprintf(buffer, buflen, "lib%s.so", fname); 3.23 + retval = true; 3.24 } else if (strchr(pname, *os::path_separator()) != NULL) { 3.25 int n; 3.26 char** pelements = split_path(pname, &n); 3.27 @@ -1916,6 +1917,7 @@ 3.28 } 3.29 snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname); 3.30 if (file_exists(buffer)) { 3.31 + retval = true; 3.32 break; 3.33 } 3.34 } 3.35 @@ -1930,7 +1932,9 @@ 3.36 } 3.37 } else { 3.38 snprintf(buffer, buflen, "%s/lib%s.so", pname, fname); 3.39 - } 3.40 + retval = true; 3.41 + } 3.42 + return retval; 3.43 } 3.44 3.45 const char* os::get_current_directory(char *buf, int buflen) {
4.1 --- a/src/os/windows/vm/os_windows.cpp Mon Nov 05 19:33:44 2012 -0500 4.2 +++ b/src/os/windows/vm/os_windows.cpp Wed Nov 07 17:53:02 2012 -0500 4.3 @@ -1132,21 +1132,23 @@ 4.4 return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES; 4.5 } 4.6 4.7 -void os::dll_build_name(char *buffer, size_t buflen, 4.8 +bool os::dll_build_name(char *buffer, size_t buflen, 4.9 const char* pname, const char* fname) { 4.10 + bool retval = false; 4.11 const size_t pnamelen = pname ? strlen(pname) : 0; 4.12 const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0; 4.13 4.14 - // Quietly truncates on buffer overflow. Should be an error. 4.15 + // Return error on buffer overflow. 4.16 if (pnamelen + strlen(fname) + 10 > buflen) { 4.17 - *buffer = '\0'; 4.18 - return; 4.19 + return retval; 4.20 } 4.21 4.22 if (pnamelen == 0) { 4.23 jio_snprintf(buffer, buflen, "%s.dll", fname); 4.24 + retval = true; 4.25 } else if (c == ':' || c == '\\') { 4.26 jio_snprintf(buffer, buflen, "%s%s.dll", pname, fname); 4.27 + retval = true; 4.28 } else if (strchr(pname, *os::path_separator()) != NULL) { 4.29 int n; 4.30 char** pelements = split_path(pname, &n); 4.31 @@ -1164,6 +1166,7 @@ 4.32 jio_snprintf(buffer, buflen, "%s\\%s.dll", path, fname); 4.33 } 4.34 if (file_exists(buffer)) { 4.35 + retval = true; 4.36 break; 4.37 } 4.38 } 4.39 @@ -1178,7 +1181,9 @@ 4.40 } 4.41 } else { 4.42 jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname); 4.43 - } 4.44 + retval = true; 4.45 + } 4.46 + return retval; 4.47 } 4.48 4.49 // Needs to be in os specific directory because windows requires another
5.1 --- a/src/share/vm/classfile/classLoader.cpp Mon Nov 05 19:33:44 2012 -0500 5.2 +++ b/src/share/vm/classfile/classLoader.cpp Wed Nov 07 17:53:02 2012 -0500 5.3 @@ -605,8 +605,10 @@ 5.4 // Load zip library 5.5 char path[JVM_MAXPATHLEN]; 5.6 char ebuf[1024]; 5.7 - os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "zip"); 5.8 - void* handle = os::dll_load(path, ebuf, sizeof ebuf); 5.9 + void* handle = NULL; 5.10 + if (os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "zip")) { 5.11 + handle = os::dll_load(path, ebuf, sizeof ebuf); 5.12 + } 5.13 if (handle == NULL) { 5.14 vm_exit_during_initialization("Unable to load ZIP library", path); 5.15 }
6.1 --- a/src/share/vm/prims/jvmtiExport.cpp Mon Nov 05 19:33:44 2012 -0500 6.2 +++ b/src/share/vm/prims/jvmtiExport.cpp Wed Nov 07 17:53:02 2012 -0500 6.3 @@ -2177,7 +2177,7 @@ 6.4 jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) { 6.5 char ebuf[1024]; 6.6 char buffer[JVM_MAXPATHLEN]; 6.7 - void* library; 6.8 + void* library = NULL; 6.9 jint result = JNI_ERR; 6.10 6.11 // get agent name and options 6.12 @@ -2196,13 +2196,16 @@ 6.13 library = os::dll_load(agent, ebuf, sizeof ebuf); 6.14 } else { 6.15 // Try to load the agent from the standard dll directory 6.16 - os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), agent); 6.17 - library = os::dll_load(buffer, ebuf, sizeof ebuf); 6.18 + if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), 6.19 + agent)) { 6.20 + library = os::dll_load(buffer, ebuf, sizeof ebuf); 6.21 + } 6.22 if (library == NULL) { 6.23 // not found - try local path 6.24 char ns[1] = {0}; 6.25 - os::dll_build_name(buffer, sizeof(buffer), ns, agent); 6.26 - library = os::dll_load(buffer, ebuf, sizeof ebuf); 6.27 + if (os::dll_build_name(buffer, sizeof(buffer), ns, agent)) { 6.28 + library = os::dll_load(buffer, ebuf, sizeof ebuf); 6.29 + } 6.30 } 6.31 } 6.32
7.1 --- a/src/share/vm/runtime/os.cpp Mon Nov 05 19:33:44 2012 -0500 7.2 +++ b/src/share/vm/runtime/os.cpp Wed Nov 07 17:53:02 2012 -0500 7.3 @@ -397,12 +397,16 @@ 7.4 // Try to load verify dll first. In 1.3 java dll depends on it and is not 7.5 // always able to find it when the loading executable is outside the JDK. 7.6 // In order to keep working with 1.2 we ignore any loading errors. 7.7 - dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"); 7.8 - dll_load(buffer, ebuf, sizeof(ebuf)); 7.9 + if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), 7.10 + "verify")) { 7.11 + dll_load(buffer, ebuf, sizeof(ebuf)); 7.12 + } 7.13 7.14 // Load java dll 7.15 - dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java"); 7.16 - _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf)); 7.17 + if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), 7.18 + "java")) { 7.19 + _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf)); 7.20 + } 7.21 if (_native_java_library == NULL) { 7.22 vm_exit_during_initialization("Unable to load native library", ebuf); 7.23 } 7.24 @@ -410,8 +414,10 @@ 7.25 #if defined(__OpenBSD__) 7.26 // Work-around OpenBSD's lack of $ORIGIN support by pre-loading libnet.so 7.27 // ignore errors 7.28 - dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "net"); 7.29 - dll_load(buffer, ebuf, sizeof(ebuf)); 7.30 + if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), 7.31 + "net")) { 7.32 + dll_load(buffer, ebuf, sizeof(ebuf)); 7.33 + } 7.34 #endif 7.35 } 7.36 static jboolean onLoaded = JNI_FALSE; 7.37 @@ -1156,7 +1162,7 @@ 7.38 if (inpath == NULL) { 7.39 return NULL; 7.40 } 7.41 - strncpy(inpath, path, strlen(path)); 7.42 + strcpy(inpath, path); 7.43 int count = 1; 7.44 char* p = strchr(inpath, psepchar); 7.45 // Get a count of elements to allocate memory
8.1 --- a/src/share/vm/runtime/os.hpp Mon Nov 05 19:33:44 2012 -0500 8.2 +++ b/src/share/vm/runtime/os.hpp Wed Nov 07 17:53:02 2012 -0500 8.3 @@ -479,7 +479,8 @@ 8.4 static const char* get_current_directory(char *buf, int buflen); 8.5 8.6 // Builds a platform-specific full library path given a ld path and lib name 8.7 - static void dll_build_name(char* buffer, size_t size, 8.8 + // Returns true if buffer contains full path to existing file, false otherwise 8.9 + static bool dll_build_name(char* buffer, size_t size, 8.10 const char* pathname, const char* fname); 8.11 8.12 // Symbol lookup, find nearest function name; basically it implements
9.1 --- a/src/share/vm/runtime/thread.cpp Mon Nov 05 19:33:44 2012 -0500 9.2 +++ b/src/share/vm/runtime/thread.cpp Wed Nov 07 17:53:02 2012 -0500 9.3 @@ -3706,8 +3706,10 @@ 9.4 } 9.5 } else { 9.6 // Try to load the agent from the standard dll directory 9.7 - os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), name); 9.8 - library = os::dll_load(buffer, ebuf, sizeof ebuf); 9.9 + if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), 9.10 + name)) { 9.11 + library = os::dll_load(buffer, ebuf, sizeof ebuf); 9.12 + } 9.13 #ifdef KERNEL 9.14 // Download instrument dll 9.15 if (library == NULL && strcmp(name, "instrument") == 0) { 9.16 @@ -3732,8 +3734,9 @@ 9.17 #endif // KERNEL 9.18 if (library == NULL) { // Try the local directory 9.19 char ns[1] = {0}; 9.20 - os::dll_build_name(buffer, sizeof(buffer), ns, name); 9.21 - library = os::dll_load(buffer, ebuf, sizeof ebuf); 9.22 + if (os::dll_build_name(buffer, sizeof(buffer), ns, name)) { 9.23 + library = os::dll_load(buffer, ebuf, sizeof ebuf); 9.24 + } 9.25 if (library == NULL) { 9.26 const char *sub_msg = " on the library path, with error: "; 9.27 size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;