提交 72e038be 编写于 作者: J jzavgren

8008118: (process) Possible null pointer dereference in...

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
上级 0e5ba844
...@@ -217,7 +217,7 @@ SUNWprivate_1.1 { ...@@ -217,7 +217,7 @@ SUNWprivate_1.1 {
Java_java_lang_Throwable_fillInStackTrace; Java_java_lang_Throwable_fillInStackTrace;
Java_java_lang_Throwable_getStackTraceDepth; Java_java_lang_Throwable_getStackTraceDepth;
Java_java_lang_Throwable_getStackTraceElement; Java_java_lang_Throwable_getStackTraceElement;
Java_java_lang_UNIXProcess_initIDs; Java_java_lang_UNIXProcess_init;
Java_java_lang_UNIXProcess_waitForProcessExit; Java_java_lang_UNIXProcess_waitForProcessExit;
Java_java_lang_UNIXProcess_forkAndExec; Java_java_lang_UNIXProcess_forkAndExec;
Java_java_lang_UNIXProcess_destroyProcess; Java_java_lang_UNIXProcess_destroyProcess;
......
...@@ -217,7 +217,7 @@ SUNWprivate_1.1 { ...@@ -217,7 +217,7 @@ SUNWprivate_1.1 {
Java_java_lang_Throwable_fillInStackTrace; Java_java_lang_Throwable_fillInStackTrace;
Java_java_lang_Throwable_getStackTraceDepth; Java_java_lang_Throwable_getStackTraceDepth;
Java_java_lang_Throwable_getStackTraceElement; Java_java_lang_Throwable_getStackTraceElement;
Java_java_lang_UNIXProcess_initIDs; Java_java_lang_UNIXProcess_init;
Java_java_lang_UNIXProcess_waitForProcessExit; Java_java_lang_UNIXProcess_waitForProcessExit;
Java_java_lang_UNIXProcess_forkAndExec; Java_java_lang_UNIXProcess_forkAndExec;
Java_java_lang_UNIXProcess_destroyProcess; Java_java_lang_UNIXProcess_destroyProcess;
......
...@@ -270,11 +270,10 @@ final class UNIXProcess extends Process { ...@@ -270,11 +270,10 @@ final class UNIXProcess extends Process {
return !hasExited; return !hasExited;
} }
/* This routine initializes JNI field offsets for the class */ private static native void init();
private static native void initIDs();
static { static {
initIDs(); init();
} }
/** /**
......
...@@ -270,11 +270,10 @@ final class UNIXProcess extends Process { ...@@ -270,11 +270,10 @@ final class UNIXProcess extends Process {
return !hasExited; return !hasExited;
} }
/* This routine initializes JNI field offsets for the class */ private static native void init();
private static native void initIDs();
static { static {
initIDs(); init();
} }
/** /**
......
...@@ -328,10 +328,9 @@ final class UNIXProcess extends Process { ...@@ -328,10 +328,9 @@ final class UNIXProcess extends Process {
} }
/* This routine initializes JNI field offsets for the class */ private static native void init();
private static native void initIDs();
static { static {
initIDs(); init();
} }
} }
...@@ -31,21 +31,24 @@ ...@@ -31,21 +31,24 @@
#ifdef __APPLE__ #ifdef __APPLE__
#include <crt_externs.h> #include <crt_externs.h>
#define environ (*_NSGetEnviron()) #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 #endif
JNIEXPORT jobjectArray JNICALL JNIEXPORT jobjectArray JNICALL
Java_java_lang_ProcessEnvironment_environ(JNIEnv *env, jclass ign) 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 count = 0;
jsize i, j; jsize i, j;
jobjectArray result; jobjectArray result;
......
...@@ -52,6 +52,19 @@ ...@@ -52,6 +52,19 @@
#ifdef __APPLE__ #ifdef __APPLE__
#include <crt_externs.h> #include <crt_externs.h>
#define environ (*_NSGetEnviron()) #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 #endif
/* /*
...@@ -152,19 +165,6 @@ ...@@ -152,19 +165,6 @@
} while((_result == -1) && (errno == EINTR)); \ } while((_result == -1) && (errno == EINTR)); \
} while(0) } 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 static void
setSIGCHLDHandler(JNIEnv *env) setSIGCHLDHandler(JNIEnv *env)
...@@ -241,52 +241,41 @@ countOccurrences(const char *s, char c) ...@@ -241,52 +241,41 @@ countOccurrences(const char *s, char c)
} }
static const char * const * static const char * const *
splitPath(JNIEnv *env, const char *path) effectivePathv(JNIEnv *env)
{ {
const char *p, *q; char *p;
char **pathv;
int i; int i;
const char *path = effectivePath();
int count = countOccurrences(path, ':') + 1; int count = countOccurrences(path, ':') + 1;
size_t pathvsize = sizeof(const char *) * (count+1);
pathv = NEW(char*, count+1); size_t pathsize = strlen(path) + 1;
pathv[count] = NULL; const char **pathv = (const char **) xmalloc(env, pathvsize + pathsize);
for (p = path, i = 0; i < count; i++, p = q + 1) {
for (q = p; (*q != ':') && (*q != '\0'); q++) if (pathv == NULL)
; return NULL;
if (q == p) /* empty PATH component => "." */ p = (char *) pathv + pathvsize;
pathv[i] = "./"; memcpy(p, path, pathsize);
else { /* split PATH by replacing ':' with NULs; empty components => "." */
int addSlash = ((*(q - 1)) != '/'); for (i = 0; i < count; i++) {
pathv[i] = NEW(char, q - p + addSlash + 1); char *q = p + strcspn(p, ":");
memcpy(pathv[i], p, q - p); pathv[i] = (p == q) ? "." : p;
if (addSlash) *q = '\0';
pathv[i][q - p] = '/'; p = q + 1;
pathv[i][q - p + addSlash] = '\0';
}
} }
return (const char * const *) pathv; pathv[count] = NULL;
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) * (We don't support putenv("PATH=...") in native code)
*/ */
static const char *parentPath;
/**
* Split, canonicalized version of parentPath
*/
static const char * const *parentPathv; static const char * const *parentPathv;
static jfieldID field_exitcode;
JNIEXPORT void JNICALL 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"); parentPathv = effectivePathv(env);
parentPath = effectivePath();
parentPathv = splitPath(env, parentPath);
setSIGCHLDHandler(env); setSIGCHLDHandler(env);
} }
...@@ -486,6 +475,9 @@ throwIOException(JNIEnv *env, int errnum, const char *defaultDetail) ...@@ -486,6 +475,9 @@ throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
} }
/* 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));
if (errmsg == NULL)
return;
sprintf(errmsg, format, errnum, detail); sprintf(errmsg, format, errnum, detail);
s = JNU_NewStringPlatform(env, errmsg); s = JNU_NewStringPlatform(env, errmsg);
if (s != NULL) { if (s != NULL) {
...@@ -590,11 +582,13 @@ JDK_execvpe(const char *file, ...@@ -590,11 +582,13 @@ JDK_execvpe(const char *file,
for (dirs = parentPathv; *dirs; dirs++) { for (dirs = parentPathv; *dirs; dirs++) {
const char * dir = *dirs; const char * dir = *dirs;
int dirlen = strlen(dir); int dirlen = strlen(dir);
if (filelen + dirlen + 1 >= PATH_MAX) { if (filelen + dirlen + 2 >= PATH_MAX) {
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
continue; continue;
} }
memcpy(expanded_file, dir, dirlen); memcpy(expanded_file, dir, dirlen);
if (expanded_file[dirlen - 1] != '/')
expanded_file[dirlen++] = '/';
memcpy(expanded_file + dirlen, file, filelen); memcpy(expanded_file + dirlen, file, filelen);
expanded_file[dirlen + filelen] = '\0'; expanded_file[dirlen + filelen] = '\0';
execve_with_shell_fallback(expanded_file, argv, envp); execve_with_shell_fallback(expanded_file, argv, envp);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册