Integrate our deterministic OpenJDK fork with Avian (#117)

* Remove non-deterministic classes from Avian (wip).
* Complete integration between Avian and our local OpenJDK fork.
* Revert accidental Avian modification.
* Implements a "blacklist filter" for Avian's system classloader.
* Remove .DSA, .RSA, .SF and .MF files when creating a fat jar.
* Revert more accidental Avian changes.
* Fix breakage with dependencies, and retain Kryo instance.
* Apply blacklisting per thread rather than globally.
* Blacklist java.lang.ClassLoader and all java.lang.Thread* classes.
* Add comment explaining class blacklisting.
* Fix Avian when building without OpenJDK.
* Configure ProGuard to keep more classes for deserialisation.
* Retain explicit return type for secure random function.
* Add sources of random numbers to the class blacklist.
* Blacklist the threading classes more precisely.
* Make SystemClassLoader.isForbidden() static.
* Prevent ProGuard from removing SerializedLambda.readResolve().
* Remove Avian tests involving direct buffers.
This commit is contained in:
Chris Rankin
2017-11-21 17:06:18 +00:00
committed by GitHub
parent 6a631ec626
commit 4dbd404f64
78 changed files with 238 additions and 5088 deletions

View File

@ -376,103 +376,6 @@ void copyAndEscape(char** dest, const char* src, size_t length)
*dest = destp;
}
extern "C" JNIEXPORT void JNICALL
Java_java_lang_Runtime_exec(JNIEnv* e,
jclass,
jobjectArray command,
jlongArray process)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
int size = 0;
for (int i = 0; i < e->GetArrayLength(command); ++i) {
jstring element = (jstring)e->GetObjectArrayElement(command, i);
if (element) {
// worst case, assuming every character is '"', and we escape all of them
size += 2 * e->GetStringUTFLength(element) + 3;
} else {
throwNew(e,
"java/lang/NullPointerException",
strdup("null string array element"));
}
}
RUNTIME_ARRAY(char, line, size);
char* linep = RUNTIME_ARRAY_BODY(line);
for (int i = 0; i < e->GetArrayLength(command); ++i) {
if (i)
*(linep++) = _T(' ');
jstring element = (jstring)e->GetObjectArrayElement(command, i);
const char* s = e->GetStringUTFChars(element, 0);
copyAndEscape(&linep, s, e->GetStringUTFLength(element));
e->ReleaseStringUTFChars(element, s);
}
*(linep++) = _T('\0');
HANDLE in[] = {0, 0};
HANDLE out[] = {0, 0};
HANDLE err[] = {0, 0};
makePipe(e, in);
SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0);
jlong inDescriptor = static_cast<jlong>(descriptor(e, in[0]));
if (e->ExceptionCheck())
return;
e->SetLongArrayRegion(process, 2, 1, &inDescriptor);
makePipe(e, out);
SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0);
jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1]));
if (e->ExceptionCheck())
return;
e->SetLongArrayRegion(process, 3, 1, &outDescriptor);
makePipe(e, err);
SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0);
jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0]));
if (e->ExceptionCheck())
return;
e->SetLongArrayRegion(process, 4, 1, &errDescriptor);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = in[1];
si.hStdInput = out[0];
si.hStdError = err[1];
BOOL success = CreateProcess(0,
(LPSTR)RUNTIME_ARRAY_BODY(line),
0,
0,
1,
CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
0,
0,
&si,
&pi);
CloseHandle(in[1]);
CloseHandle(out[0]);
CloseHandle(err[1]);
if (not success) {
throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
return;
}
jlong pid = reinterpret_cast<jlong>(pi.hProcess);
e->SetLongArrayRegion(process, 0, 1, &pid);
jlong tid = reinterpret_cast<jlong>(pi.hThread);
e->SetLongArrayRegion(process, 1, 1, &tid);
#else
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
#endif
}
extern "C" JNIEXPORT jint JNICALL
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
{
@ -1003,60 +906,6 @@ extern "C" JNIEXPORT jobjectArray JNICALL
return array;
}
// System.getEnvironment() implementation
// TODO: For Win32, replace usage of deprecated _environ and add Unicode
// support (neither of which is likely to be of great importance).
#ifdef AVIAN_IOS
namespace {
const char* environ[] = {0};
}
#elif defined __APPLE__
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
#elif defined(WINAPI_FAMILY) \
&& !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
// WinRT/WP8 does not provide alternative for environment variables
char* environ[] = {0};
#else
extern char** environ;
#endif
extern "C" JNIEXPORT jobjectArray JNICALL
Java_java_lang_System_getEnvironment(JNIEnv* env, jclass)
{
int length;
for (length = 0; environ[length] != 0; ++length)
;
jobjectArray stringArray = env->NewObjectArray(
length, env->FindClass("java/lang/String"), env->NewStringUTF(""));
for (int i = 0; i < length; i++) {
jobject varString = env->NewStringUTF(environ[i]);
env->SetObjectArrayElement(stringArray, i, varString);
}
return stringArray;
}
extern "C" JNIEXPORT jlong JNICALL
Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass)
{
#ifdef PLATFORM_WINDOWS
// We used to use _ftime here, but that only gives us 1-second
// resolution on Windows 7. _ftime_s might work better, but MinGW
// doesn't have it as of this writing. So we use this mess instead:
FILETIME time;
GetSystemTimeAsFileTime(&time);
return (((static_cast<jlong>(time.dwHighDateTime) << 32) | time.dwLowDateTime)
/ 10000) - 11644473600000LL;
#else
timeval tv = {0, 0};
gettimeofday(&tv, 0);
return (static_cast<jlong>(tv.tv_sec) * 1000)
+ (static_cast<jlong>(tv.tv_usec) / 1000);
#endif
}
extern "C" JNIEXPORT jstring JNICALL
Java_java_lang_System_doMapLibraryName(JNIEnv* e, jclass, jstring name)
{