8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken

Wed, 07 Nov 2012 17:53:02 -0500

author
bpittore
date
Wed, 07 Nov 2012 17:53:02 -0500
changeset 4261
6cb0d32b828b
parent 4243
857f3ce858dd
child 4262
d9a84e246cce

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

src/os/bsd/vm/os_bsd.cpp file | annotate | diff | comparison | revisions
src/os/linux/vm/os_linux.cpp file | annotate | diff | comparison | revisions
src/os/solaris/vm/os_solaris.cpp file | annotate | diff | comparison | revisions
src/os/windows/vm/os_windows.cpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/classLoader.cpp file | annotate | diff | comparison | revisions
src/share/vm/prims/jvmtiExport.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/os.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/os.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/thread.cpp file | annotate | diff | comparison | revisions
     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;

mercurial