8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c
authorjzavgren
Thu, 11 Apr 2013 12:33:33 -0400
changeset 16860 8fecebee12b0
parent 16859 45fbee947921
child 16861 9dd215f8cc5a
child 16902 986f53b29dcc
8008118: (process) Possible null pointer dereference in jdk/src/solaris/native/java/lang/UNIXProcess_md.c Summary: Modified the path processing code so that it detects and handles out of memory errors. Reviewed-by: chegar, martin, christos, alanb, msheppar Contributed-by: john.zavgren@oracle.com
jdk/make/java/java/mapfile-vers
jdk/makefiles/mapfiles/libjava/mapfile-vers
jdk/src/solaris/classes/java/lang/UNIXProcess.java.bsd
jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux
jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris
jdk/src/solaris/native/java/lang/ProcessEnvironment_md.c
jdk/src/solaris/native/java/lang/UNIXProcess_md.c
--- a/jdk/make/java/java/mapfile-vers	Fri Apr 12 20:23:13 2013 -0700
+++ b/jdk/make/java/java/mapfile-vers	Thu Apr 11 12:33:33 2013 -0400
@@ -217,7 +217,7 @@
 		Java_java_lang_Throwable_fillInStackTrace;
                 Java_java_lang_Throwable_getStackTraceDepth;
                 Java_java_lang_Throwable_getStackTraceElement;
-		Java_java_lang_UNIXProcess_initIDs;
+		Java_java_lang_UNIXProcess_init;
 		Java_java_lang_UNIXProcess_waitForProcessExit;
 		Java_java_lang_UNIXProcess_forkAndExec;
 		Java_java_lang_UNIXProcess_destroyProcess;
--- a/jdk/makefiles/mapfiles/libjava/mapfile-vers	Fri Apr 12 20:23:13 2013 -0700
+++ b/jdk/makefiles/mapfiles/libjava/mapfile-vers	Thu Apr 11 12:33:33 2013 -0400
@@ -217,7 +217,7 @@
 		Java_java_lang_Throwable_fillInStackTrace;
                 Java_java_lang_Throwable_getStackTraceDepth;
                 Java_java_lang_Throwable_getStackTraceElement;
-		Java_java_lang_UNIXProcess_initIDs;
+		Java_java_lang_UNIXProcess_init;
 		Java_java_lang_UNIXProcess_waitForProcessExit;
 		Java_java_lang_UNIXProcess_forkAndExec;
 		Java_java_lang_UNIXProcess_destroyProcess;
--- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.bsd	Fri Apr 12 20:23:13 2013 -0700
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.bsd	Thu Apr 11 12:33:33 2013 -0400
@@ -270,11 +270,10 @@
         return !hasExited;
     }
 
-    /* This routine initializes JNI field offsets for the class */
-    private static native void initIDs();
+    private static native void init();
 
     static {
-        initIDs();
+        init();
     }
 
     /**
--- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux	Fri Apr 12 20:23:13 2013 -0700
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux	Thu Apr 11 12:33:33 2013 -0400
@@ -270,11 +270,10 @@
         return !hasExited;
     }
 
-    /* This routine initializes JNI field offsets for the class */
-    private static native void initIDs();
+    private static native void init();
 
     static {
-        initIDs();
+        init();
     }
 
     /**
--- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris	Fri Apr 12 20:23:13 2013 -0700
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris	Thu Apr 11 12:33:33 2013 -0400
@@ -328,10 +328,9 @@
 
     }
 
-    /* This routine initializes JNI field offsets for the class */
-    private static native void initIDs();
+    private static native void init();
 
     static {
-        initIDs();
+        init();
     }
 }
--- a/jdk/src/solaris/native/java/lang/ProcessEnvironment_md.c	Fri Apr 12 20:23:13 2013 -0700
+++ b/jdk/src/solaris/native/java/lang/ProcessEnvironment_md.c	Thu Apr 11 12:33:33 2013 -0400
@@ -31,21 +31,24 @@
 #ifdef __APPLE__
 #include <crt_externs.h>
 #define environ (*_NSGetEnviron())
+#else
+/* This is one of the rare times it's more portable to declare an
+ * external symbol explicitly, rather than via a system header.
+ * The declaration is standardized as part of UNIX98, but there is
+ * no standard (not even de-facto) header file where the
+ * declaration is to be found.  See:
+ * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
+ * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
+ *
+ * "All identifiers in this volume of IEEE Std 1003.1-2001, except
+ * environ, are defined in at least one of the headers" (!)
+ */
+extern char **environ;
 #endif
 
 JNIEXPORT jobjectArray JNICALL
 Java_java_lang_ProcessEnvironment_environ(JNIEnv *env, jclass ign)
 {
-    /* This is one of the rare times it's more portable to declare an
-     * external symbol explicitly, rather than via a system header.
-     * The declaration is standardized as part of UNIX98, but there is
-     * no standard (not even de-facto) header file where the
-     * declaration is to be found.  See:
-     * http://www.opengroup.org/onlinepubs/007908799/xbd/envvar.html */
-#ifndef __APPLE__
-    extern char ** environ; /* environ[i] looks like: VAR=VALUE\0 */
-#endif
-
     jsize count = 0;
     jsize i, j;
     jobjectArray result;
--- a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c	Fri Apr 12 20:23:13 2013 -0700
+++ b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c	Thu Apr 11 12:33:33 2013 -0400
@@ -52,6 +52,19 @@
 #ifdef __APPLE__
 #include <crt_externs.h>
 #define environ (*_NSGetEnviron())
+#else
+/* This is one of the rare times it's more portable to declare an
+ * external symbol explicitly, rather than via a system header.
+ * The declaration is standardized as part of UNIX98, but there is
+ * no standard (not even de-facto) header file where the
+ * declaration is to be found.  See:
+ * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
+ * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
+ *
+ * "All identifiers in this volume of IEEE Std 1003.1-2001, except
+ * environ, are defined in at least one of the headers" (!)
+ */
+extern char **environ;
 #endif
 
 /*
@@ -152,19 +165,6 @@
   } while((_result == -1) && (errno == EINTR)); \
 } while(0)
 
-/* This is one of the rare times it's more portable to declare an
- * external symbol explicitly, rather than via a system header.
- * The declaration is standardized as part of UNIX98, but there is
- * no standard (not even de-facto) header file where the
- * declaration is to be found.  See:
- * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
- * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
- *
- * "All identifiers in this volume of IEEE Std 1003.1-2001, except
- * environ, are defined in at least one of the headers" (!)
- */
-extern char **environ;
-
 
 static void
 setSIGCHLDHandler(JNIEnv *env)
@@ -241,52 +241,41 @@
 }
 
 static const char * const *
-splitPath(JNIEnv *env, const char *path)
+effectivePathv(JNIEnv *env)
 {
-    const char *p, *q;
-    char **pathv;
+    char *p;
     int i;
+    const char *path = effectivePath();
     int count = countOccurrences(path, ':') + 1;
+    size_t pathvsize = sizeof(const char *) * (count+1);
+    size_t pathsize = strlen(path) + 1;
+    const char **pathv = (const char **) xmalloc(env, pathvsize + pathsize);
 
-    pathv = NEW(char*, count+1);
+    if (pathv == NULL)
+        return NULL;
+    p = (char *) pathv + pathvsize;
+    memcpy(p, path, pathsize);
+    /* split PATH by replacing ':' with NULs; empty components => "." */
+    for (i = 0; i < count; i++) {
+        char *q = p + strcspn(p, ":");
+        pathv[i] = (p == q) ? "." : p;
+        *q = '\0';
+        p = q + 1;
+    }
     pathv[count] = NULL;
-    for (p = path, i = 0; i < count; i++, p = q + 1) {
-        for (q = p; (*q != ':') && (*q != '\0'); q++)
-            ;
-        if (q == p)             /* empty PATH component => "." */
-            pathv[i] = "./";
-        else {
-            int addSlash = ((*(q - 1)) != '/');
-            pathv[i] = NEW(char, q - p + addSlash + 1);
-            memcpy(pathv[i], p, q - p);
-            if (addSlash)
-                pathv[i][q - p] = '/';
-            pathv[i][q - p + addSlash] = '\0';
-        }
-    }
-    return (const char * const *) pathv;
+    return pathv;
 }
 
 /**
- * Cached value of JVM's effective PATH.
+ * The cached and split version of the JDK's effective PATH.
  * (We don't support putenv("PATH=...") in native code)
  */
-static const char *parentPath;
-
-/**
- * Split, canonicalized version of parentPath
- */
 static const char * const *parentPathv;
 
-static jfieldID field_exitcode;
-
 JNIEXPORT void JNICALL
-Java_java_lang_UNIXProcess_initIDs(JNIEnv *env, jclass clazz)
+Java_java_lang_UNIXProcess_init(JNIEnv *env, jclass clazz)
 {
-    field_exitcode = (*env)->GetFieldID(env, clazz, "exitcode", "I");
-
-    parentPath  = effectivePath();
-    parentPathv = splitPath(env, parentPath);
+    parentPathv = effectivePathv(env);
 
     setSIGCHLDHandler(env);
 }
@@ -486,6 +475,9 @@
     }
     /* ASCII Decimal representation uses 2.4 times as many bits as binary. */
     errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum));
+    if (errmsg == NULL)
+        return;
+
     sprintf(errmsg, format, errnum, detail);
     s = JNU_NewStringPlatform(env, errmsg);
     if (s != NULL) {
@@ -590,11 +582,13 @@
         for (dirs = parentPathv; *dirs; dirs++) {
             const char * dir = *dirs;
             int dirlen = strlen(dir);
-            if (filelen + dirlen + 1 >= PATH_MAX) {
+            if (filelen + dirlen + 2 >= PATH_MAX) {
                 errno = ENAMETOOLONG;
                 continue;
             }
             memcpy(expanded_file, dir, dirlen);
+            if (expanded_file[dirlen - 1] != '/')
+                expanded_file[dirlen++] = '/';
             memcpy(expanded_file + dirlen, file, filelen);
             expanded_file[dirlen + filelen] = '\0';
             execve_with_shell_fallback(expanded_file, argv, envp);