8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
authorbpittore
Wed, 07 Nov 2012 17:53:02 -0500
changeset 14471 f3a6b82e25cf
parent 14383 f31aacbd0f36
child 14472 31ed75482688
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
hotspot/src/os/bsd/vm/os_bsd.cpp
hotspot/src/os/linux/vm/os_linux.cpp
hotspot/src/os/solaris/vm/os_solaris.cpp
hotspot/src/os/windows/vm/os_windows.cpp
hotspot/src/share/vm/classfile/classLoader.cpp
hotspot/src/share/vm/prims/jvmtiExport.cpp
hotspot/src/share/vm/runtime/os.cpp
hotspot/src/share/vm/runtime/os.hpp
hotspot/src/share/vm/runtime/thread.cpp
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Mon Nov 05 19:33:44 2012 -0500
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Wed Nov 07 17:53:02 2012 -0500
@@ -1198,19 +1198,20 @@
   return os::stat(filename, &statbuf) == 0;
 }
 
-void os::dll_build_name(char* buffer, size_t buflen,
+bool os::dll_build_name(char* buffer, size_t buflen,
                         const char* pname, const char* fname) {
+  bool retval = false;
   // Copied from libhpi
   const size_t pnamelen = pname ? strlen(pname) : 0;
 
-  // Quietly truncate on buffer overflow.  Should be an error.
+  // Return error on buffer overflow.
   if (pnamelen + strlen(fname) + strlen(JNI_LIB_PREFIX) + strlen(JNI_LIB_SUFFIX) + 2 > buflen) {
-      *buffer = '\0';
-      return;
+    return retval;
   }
 
   if (pnamelen == 0) {
     snprintf(buffer, buflen, JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, fname);
+    retval = true;
   } else if (strchr(pname, *os::path_separator()) != NULL) {
     int n;
     char** pelements = split_path(pname, &n);
@@ -1222,6 +1223,7 @@
       snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX,
           pelements[i], fname);
       if (file_exists(buffer)) {
+        retval = true;
         break;
       }
     }
@@ -1236,7 +1238,9 @@
     }
   } else {
     snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname);
+    retval = true;
   }
+  return retval;
 }
 
 const char* os::get_current_directory(char *buf, int buflen) {
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Mon Nov 05 19:33:44 2012 -0500
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Wed Nov 07 17:53:02 2012 -0500
@@ -1650,19 +1650,20 @@
   return os::stat(filename, &statbuf) == 0;
 }
 
-void os::dll_build_name(char* buffer, size_t buflen,
+bool os::dll_build_name(char* buffer, size_t buflen,
                         const char* pname, const char* fname) {
+  bool retval = false;
   // Copied from libhpi
   const size_t pnamelen = pname ? strlen(pname) : 0;
 
-  // Quietly truncate on buffer overflow.  Should be an error.
+  // Return error on buffer overflow.
   if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
-      *buffer = '\0';
-      return;
+    return retval;
   }
 
   if (pnamelen == 0) {
     snprintf(buffer, buflen, "lib%s.so", fname);
+    retval = true;
   } else if (strchr(pname, *os::path_separator()) != NULL) {
     int n;
     char** pelements = split_path(pname, &n);
@@ -1673,6 +1674,7 @@
       }
       snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
       if (file_exists(buffer)) {
+        retval = true;
         break;
       }
     }
@@ -1687,7 +1689,9 @@
     }
   } else {
     snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
-  }
+    retval = true;
+  }
+  return retval;
 }
 
 const char* os::get_current_directory(char *buf, int buflen) {
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Mon Nov 05 19:33:44 2012 -0500
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Nov 07 17:53:02 2012 -0500
@@ -1894,18 +1894,19 @@
   return os::stat(filename, &statbuf) == 0;
 }
 
-void os::dll_build_name(char* buffer, size_t buflen,
+bool os::dll_build_name(char* buffer, size_t buflen,
                         const char* pname, const char* fname) {
+  bool retval = false;
   const size_t pnamelen = pname ? strlen(pname) : 0;
 
-  // Quietly truncate on buffer overflow.  Should be an error.
+  // Return error on buffer overflow.
   if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
-    *buffer = '\0';
-    return;
+    return retval;
   }
 
   if (pnamelen == 0) {
     snprintf(buffer, buflen, "lib%s.so", fname);
+    retval = true;
   } else if (strchr(pname, *os::path_separator()) != NULL) {
     int n;
     char** pelements = split_path(pname, &n);
@@ -1916,6 +1917,7 @@
       }
       snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
       if (file_exists(buffer)) {
+        retval = true;
         break;
       }
     }
@@ -1930,7 +1932,9 @@
     }
   } else {
     snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
-  }
+    retval = true;
+  }
+  return retval;
 }
 
 const char* os::get_current_directory(char *buf, int buflen) {
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Mon Nov 05 19:33:44 2012 -0500
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Nov 07 17:53:02 2012 -0500
@@ -1132,21 +1132,23 @@
   return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES;
 }
 
-void os::dll_build_name(char *buffer, size_t buflen,
+bool os::dll_build_name(char *buffer, size_t buflen,
                         const char* pname, const char* fname) {
+  bool retval = false;
   const size_t pnamelen = pname ? strlen(pname) : 0;
   const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
 
-  // Quietly truncates on buffer overflow. Should be an error.
+  // Return error on buffer overflow.
   if (pnamelen + strlen(fname) + 10 > buflen) {
-    *buffer = '\0';
-    return;
+    return retval;
   }
 
   if (pnamelen == 0) {
     jio_snprintf(buffer, buflen, "%s.dll", fname);
+    retval = true;
   } else if (c == ':' || c == '\\') {
     jio_snprintf(buffer, buflen, "%s%s.dll", pname, fname);
+    retval = true;
   } else if (strchr(pname, *os::path_separator()) != NULL) {
     int n;
     char** pelements = split_path(pname, &n);
@@ -1164,6 +1166,7 @@
         jio_snprintf(buffer, buflen, "%s\\%s.dll", path, fname);
       }
       if (file_exists(buffer)) {
+        retval = true;
         break;
       }
     }
@@ -1178,7 +1181,9 @@
     }
   } else {
     jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname);
-  }
+    retval = true;
+  }
+  return retval;
 }
 
 // Needs to be in os specific directory because windows requires another
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Mon Nov 05 19:33:44 2012 -0500
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Wed Nov 07 17:53:02 2012 -0500
@@ -605,8 +605,10 @@
   // Load zip library
   char path[JVM_MAXPATHLEN];
   char ebuf[1024];
-  os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "zip");
-  void* handle = os::dll_load(path, ebuf, sizeof ebuf);
+  void* handle = NULL;
+  if (os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "zip")) {
+    handle = os::dll_load(path, ebuf, sizeof ebuf);
+  }
   if (handle == NULL) {
     vm_exit_during_initialization("Unable to load ZIP library", path);
   }
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp	Mon Nov 05 19:33:44 2012 -0500
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp	Wed Nov 07 17:53:02 2012 -0500
@@ -2177,7 +2177,7 @@
 jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) {
   char ebuf[1024];
   char buffer[JVM_MAXPATHLEN];
-  void* library;
+  void* library = NULL;
   jint result = JNI_ERR;
 
   // get agent name and options
@@ -2196,13 +2196,16 @@
     library = os::dll_load(agent, ebuf, sizeof ebuf);
   } else {
     // Try to load the agent from the standard dll directory
-    os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), agent);
-    library = os::dll_load(buffer, ebuf, sizeof ebuf);
+    if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
+                           agent)) {
+      library = os::dll_load(buffer, ebuf, sizeof ebuf);
+    }
     if (library == NULL) {
       // not found - try local path
       char ns[1] = {0};
-      os::dll_build_name(buffer, sizeof(buffer), ns, agent);
-      library = os::dll_load(buffer, ebuf, sizeof ebuf);
+      if (os::dll_build_name(buffer, sizeof(buffer), ns, agent)) {
+        library = os::dll_load(buffer, ebuf, sizeof ebuf);
+      }
     }
   }
 
--- a/hotspot/src/share/vm/runtime/os.cpp	Mon Nov 05 19:33:44 2012 -0500
+++ b/hotspot/src/share/vm/runtime/os.cpp	Wed Nov 07 17:53:02 2012 -0500
@@ -397,12 +397,16 @@
     // Try to load verify dll first. In 1.3 java dll depends on it and is not
     // always able to find it when the loading executable is outside the JDK.
     // In order to keep working with 1.2 we ignore any loading errors.
-    dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify");
-    dll_load(buffer, ebuf, sizeof(ebuf));
+    if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
+                       "verify")) {
+      dll_load(buffer, ebuf, sizeof(ebuf));
+    }
 
     // Load java dll
-    dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java");
-    _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf));
+    if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
+                       "java")) {
+      _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf));
+    }
     if (_native_java_library == NULL) {
       vm_exit_during_initialization("Unable to load native library", ebuf);
     }
@@ -410,8 +414,10 @@
 #if defined(__OpenBSD__)
     // Work-around OpenBSD's lack of $ORIGIN support by pre-loading libnet.so
     // ignore errors
-    dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "net");
-    dll_load(buffer, ebuf, sizeof(ebuf));
+    if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
+                       "net")) {
+      dll_load(buffer, ebuf, sizeof(ebuf));
+    }
 #endif
   }
   static jboolean onLoaded = JNI_FALSE;
@@ -1156,7 +1162,7 @@
   if (inpath == NULL) {
     return NULL;
   }
-  strncpy(inpath, path, strlen(path));
+  strcpy(inpath, path);
   int count = 1;
   char* p = strchr(inpath, psepchar);
   // Get a count of elements to allocate memory
--- a/hotspot/src/share/vm/runtime/os.hpp	Mon Nov 05 19:33:44 2012 -0500
+++ b/hotspot/src/share/vm/runtime/os.hpp	Wed Nov 07 17:53:02 2012 -0500
@@ -479,7 +479,8 @@
   static const char*    get_current_directory(char *buf, int buflen);
 
   // Builds a platform-specific full library path given a ld path and lib name
-  static void           dll_build_name(char* buffer, size_t size,
+  // Returns true if buffer contains full path to existing file, false otherwise
+  static bool           dll_build_name(char* buffer, size_t size,
                                        const char* pathname, const char* fname);
 
   // Symbol lookup, find nearest function name; basically it implements
--- a/hotspot/src/share/vm/runtime/thread.cpp	Mon Nov 05 19:33:44 2012 -0500
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Wed Nov 07 17:53:02 2012 -0500
@@ -3706,8 +3706,10 @@
       }
     } else {
       // Try to load the agent from the standard dll directory
-      os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), name);
-      library = os::dll_load(buffer, ebuf, sizeof ebuf);
+      if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
+                             name)) {
+        library = os::dll_load(buffer, ebuf, sizeof ebuf);
+      }
 #ifdef KERNEL
       // Download instrument dll
       if (library == NULL && strcmp(name, "instrument") == 0) {
@@ -3732,8 +3734,9 @@
 #endif // KERNEL
       if (library == NULL) { // Try the local directory
         char ns[1] = {0};
-        os::dll_build_name(buffer, sizeof(buffer), ns, name);
-        library = os::dll_load(buffer, ebuf, sizeof ebuf);
+        if (os::dll_build_name(buffer, sizeof(buffer), ns, name)) {
+          library = os::dll_load(buffer, ebuf, sizeof ebuf);
+        }
         if (library == NULL) {
           const char *sub_msg = " on the library path, with error: ";
           size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;