mirror of
https://github.com/corda/corda.git
synced 2025-06-23 09:25:36 +00:00
specify valid code source for system classes
This enables use of a class's protection domain to determine what JAR or directory it came from.
This commit is contained in:
@ -10,14 +10,28 @@
|
|||||||
|
|
||||||
package avian;
|
package avian;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.security.CodeSource;
|
||||||
import java.security.AllPermission;
|
import java.security.AllPermission;
|
||||||
import java.security.Permissions;
|
import java.security.Permissions;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
|
||||||
public class OpenJDK {
|
public class OpenJDK {
|
||||||
public static ProtectionDomain getProtectionDomain() {
|
public static ProtectionDomain getProtectionDomain(VMClass c) {
|
||||||
|
CodeSource source = null;
|
||||||
|
if (c.source != null) {
|
||||||
|
try {
|
||||||
|
source = new CodeSource
|
||||||
|
(new URL(new String(c.source, 0, c.source.length - 1)),
|
||||||
|
(Certificate[]) null);
|
||||||
|
} catch (MalformedURLException ignored) { }
|
||||||
|
}
|
||||||
|
|
||||||
Permissions p = new Permissions();
|
Permissions p = new Permissions();
|
||||||
p.add(new AllPermission());
|
p.add(new AllPermission());
|
||||||
return new ProtectionDomain(null, p);
|
|
||||||
|
return new ProtectionDomain(source, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,8 @@ public class VMClass {
|
|||||||
public VMMethod[] virtualTable;
|
public VMMethod[] virtualTable;
|
||||||
public VMField[] fieldTable;
|
public VMField[] fieldTable;
|
||||||
public VMMethod[] methodTable;
|
public VMMethod[] methodTable;
|
||||||
public avian.ClassAddendum addendum;
|
public ClassAddendum addendum;
|
||||||
public Object staticTable;
|
public Object staticTable;
|
||||||
public ClassLoader loader;
|
public ClassLoader loader;
|
||||||
|
public byte[] source;
|
||||||
}
|
}
|
||||||
|
@ -10,4 +10,17 @@
|
|||||||
|
|
||||||
package java.security;
|
package java.security;
|
||||||
|
|
||||||
public class CodeSource { }
|
import java.net.URL;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
|
||||||
|
public class CodeSource {
|
||||||
|
private final URL url;
|
||||||
|
|
||||||
|
public CodeSource(URL url, Certificate[] certificates) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getLocation() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
13
classpath/java/security/cert/Certificate.java
Normal file
13
classpath/java/security/cert/Certificate.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/* Copyright (c) 2011, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
package java.security.cert;
|
||||||
|
|
||||||
|
public abstract class Certificate { }
|
@ -3667,22 +3667,25 @@ EXPORT(JVM_SetClassSigners)(Thread* t, jclass c, jobjectArray signers)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
jvmGetProtectionDomain(Thread* t, uintptr_t*)
|
jvmGetProtectionDomain(Thread* t, uintptr_t* arguments)
|
||||||
{
|
{
|
||||||
object openJDK = resolveClass
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
||||||
(t, root(t, Machine::BootLoader), "avian/OpenJDK");
|
|
||||||
|
|
||||||
object method = resolveMethod
|
object method = resolveMethod
|
||||||
(t, openJDK, "getProtectionDomain", "()Ljava/security/ProtectionDomain;");
|
(t, root(t, Machine::BootLoader), "avian/OpenJDK", "getProtectionDomain",
|
||||||
|
"(Lavian/VMClass;)Ljava/security/ProtectionDomain;");
|
||||||
|
|
||||||
return reinterpret_cast<uint64_t>
|
return reinterpret_cast<uint64_t>
|
||||||
(makeLocalReference(t, t->m->processor->invoke(t, method, 0)));
|
(makeLocalReference
|
||||||
|
(t, t->m->processor->invoke(t, method, 0, jclassVmClass(t, *c))));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jobject JNICALL
|
extern "C" JNIEXPORT jobject JNICALL
|
||||||
EXPORT(JVM_GetProtectionDomain)(Thread* t, jclass)
|
EXPORT(JVM_GetProtectionDomain)(Thread* t, jclass c)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<jobject>(run(t, jvmGetProtectionDomain, 0));
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c) };
|
||||||
|
|
||||||
|
return reinterpret_cast<jobject>(run(t, jvmGetProtectionDomain, arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
@ -8234,8 +8234,8 @@ class MyProcessor: public Processor {
|
|||||||
{
|
{
|
||||||
return vm::makeClass
|
return vm::makeClass
|
||||||
(t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions,
|
(t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions,
|
||||||
0, objectMask, name, sourceFile, super, interfaceTable,
|
0, objectMask, name, sourceFile, super, interfaceTable, virtualTable,
|
||||||
virtualTable, fieldTable, methodTable, staticTable, addendum, loader,
|
fieldTable, methodTable, staticTable, addendum, loader, 0,
|
||||||
vtableLength);
|
vtableLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,17 @@ append(Allocator* allocator, const char* a, const char* b, const char* c)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char*
|
||||||
|
append(Allocator* allocator, const char* a, const char* b)
|
||||||
|
{
|
||||||
|
unsigned al = strlen(a);
|
||||||
|
unsigned bl = strlen(b);
|
||||||
|
char* p = static_cast<char*>(allocator->allocate((al + bl) + 1));
|
||||||
|
memcpy(p, a, al);
|
||||||
|
memcpy(p + al, b, bl + 1);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
copy(Allocator* allocator, const char* a)
|
copy(Allocator* allocator, const char* a)
|
||||||
{
|
{
|
||||||
@ -56,6 +67,7 @@ class Element {
|
|||||||
virtual System::FileType stat(const char* name, unsigned* length,
|
virtual System::FileType stat(const char* name, unsigned* length,
|
||||||
bool tryDirectory) = 0;
|
bool tryDirectory) = 0;
|
||||||
virtual const char* urlPrefix() = 0;
|
virtual const char* urlPrefix() = 0;
|
||||||
|
virtual const char* sourceUrl() = 0;
|
||||||
virtual void dispose() = 0;
|
virtual void dispose() = 0;
|
||||||
|
|
||||||
Element* next;
|
Element* next;
|
||||||
@ -125,7 +137,8 @@ class DirectoryElement: public Element {
|
|||||||
|
|
||||||
DirectoryElement(System* s, Allocator* allocator, const char* name):
|
DirectoryElement(System* s, Allocator* allocator, const char* name):
|
||||||
s(s), allocator(allocator), name(name),
|
s(s), allocator(allocator), name(name),
|
||||||
urlPrefix_(append(allocator, "file:", name, "/"))
|
urlPrefix_(append(allocator, "file:", name, "/")),
|
||||||
|
sourceUrl_(append(allocator, "file:", name))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual Element::Iterator* iterator() {
|
virtual Element::Iterator* iterator() {
|
||||||
@ -163,9 +176,14 @@ class DirectoryElement: public Element {
|
|||||||
return urlPrefix_;
|
return urlPrefix_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual const char* sourceUrl() {
|
||||||
|
return sourceUrl_;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
allocator->free(name, strlen(name) + 1);
|
allocator->free(name, strlen(name) + 1);
|
||||||
allocator->free(urlPrefix_, strlen(urlPrefix_) + 1);
|
allocator->free(urlPrefix_, strlen(urlPrefix_) + 1);
|
||||||
|
allocator->free(sourceUrl_, strlen(sourceUrl_) + 1);
|
||||||
allocator->free(this, sizeof(*this));
|
allocator->free(this, sizeof(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,6 +191,7 @@ class DirectoryElement: public Element {
|
|||||||
Allocator* allocator;
|
Allocator* allocator;
|
||||||
const char* name;
|
const char* name;
|
||||||
const char* urlPrefix_;
|
const char* urlPrefix_;
|
||||||
|
const char* sourceUrl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PointerRegion: public System::Region {
|
class PointerRegion: public System::Region {
|
||||||
@ -438,6 +457,7 @@ class JarElement: public Element {
|
|||||||
JarElement(System* s, Allocator* allocator, const char* name):
|
JarElement(System* s, Allocator* allocator, const char* name):
|
||||||
s(s), allocator(allocator), name(name),
|
s(s), allocator(allocator), name(name),
|
||||||
urlPrefix_(name ? append(allocator, "jar:file:", name, "!/") : 0),
|
urlPrefix_(name ? append(allocator, "jar:file:", name, "!/") : 0),
|
||||||
|
sourceUrl_(name ? append(allocator, "file:", name) : 0),
|
||||||
region(0), index(0)
|
region(0), index(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -447,6 +467,7 @@ class JarElement: public Element {
|
|||||||
allocator(allocator),
|
allocator(allocator),
|
||||||
name(0),
|
name(0),
|
||||||
urlPrefix_(name ? append(allocator, "jar:file:", name, "!/") : 0),
|
urlPrefix_(name ? append(allocator, "jar:file:", name, "!/") : 0),
|
||||||
|
sourceUrl_(name ? append(allocator, "file:", name) : 0),
|
||||||
region(new (allocator->allocate(sizeof(PointerRegion)))
|
region(new (allocator->allocate(sizeof(PointerRegion)))
|
||||||
PointerRegion(s, allocator, jarData, jarLength)),
|
PointerRegion(s, allocator, jarData, jarLength)),
|
||||||
index(JarIndex::open(s, allocator, region))
|
index(JarIndex::open(s, allocator, region))
|
||||||
@ -500,6 +521,10 @@ class JarElement: public Element {
|
|||||||
return urlPrefix_;
|
return urlPrefix_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual const char* sourceUrl() {
|
||||||
|
return sourceUrl_;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
dispose(sizeof(*this));
|
dispose(sizeof(*this));
|
||||||
}
|
}
|
||||||
@ -507,6 +532,7 @@ class JarElement: public Element {
|
|||||||
virtual void dispose(unsigned size) {
|
virtual void dispose(unsigned size) {
|
||||||
allocator->free(name, strlen(name) + 1);
|
allocator->free(name, strlen(name) + 1);
|
||||||
allocator->free(urlPrefix_, strlen(urlPrefix_) + 1);
|
allocator->free(urlPrefix_, strlen(urlPrefix_) + 1);
|
||||||
|
allocator->free(sourceUrl_, strlen(sourceUrl_) + 1);
|
||||||
if (index) {
|
if (index) {
|
||||||
index->dispose();
|
index->dispose();
|
||||||
}
|
}
|
||||||
@ -520,6 +546,7 @@ class JarElement: public Element {
|
|||||||
Allocator* allocator;
|
Allocator* allocator;
|
||||||
const char* name;
|
const char* name;
|
||||||
const char* urlPrefix_;
|
const char* urlPrefix_;
|
||||||
|
const char* sourceUrl_;
|
||||||
System::Region* region;
|
System::Region* region;
|
||||||
JarIndex* index;
|
JarIndex* index;
|
||||||
};
|
};
|
||||||
@ -556,6 +583,10 @@ class BuiltinElement: public JarElement {
|
|||||||
return "resource:";
|
return "resource:";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual const char* sourceUrl() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
library->disposeAll();
|
library->disposeAll();
|
||||||
if (libraryName) {
|
if (libraryName) {
|
||||||
@ -802,6 +833,18 @@ class MyFinder: public Finder {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual const char* sourceUrl(const char* name) {
|
||||||
|
for (Element* e = path_; e; e = e->next) {
|
||||||
|
unsigned length;
|
||||||
|
System::FileType type = e->stat(name, &length, true);
|
||||||
|
if (type != System::TypeDoesNotExist) {
|
||||||
|
return e->sourceUrl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual const char* path() {
|
virtual const char* path() {
|
||||||
return pathString;
|
return pathString;
|
||||||
}
|
}
|
||||||
|
@ -168,6 +168,7 @@ class Finder {
|
|||||||
unsigned* length,
|
unsigned* length,
|
||||||
bool tryDirectory = false) = 0;
|
bool tryDirectory = false) = 0;
|
||||||
virtual const char* urlPrefix(const char* name) = 0;
|
virtual const char* urlPrefix(const char* name) = 0;
|
||||||
|
virtual const char* sourceUrl(const char* name) = 0;
|
||||||
virtual const char* path() = 0;
|
virtual const char* path() = 0;
|
||||||
virtual void dispose() = 0;
|
virtual void dispose() = 0;
|
||||||
};
|
};
|
||||||
|
@ -2982,7 +2982,7 @@ class MyProcessor: public Processor {
|
|||||||
return vm::makeClass
|
return vm::makeClass
|
||||||
(t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions, 0,
|
(t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions, 0,
|
||||||
objectMask, name, sourceFile, super, interfaceTable, virtualTable,
|
objectMask, name, sourceFile, super, interfaceTable, virtualTable,
|
||||||
fieldTable, methodTable, addendum, staticTable, loader, 0);
|
fieldTable, methodTable, addendum, staticTable, loader, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
|
@ -3320,6 +3320,7 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size,
|
|||||||
0, // addendum
|
0, // addendum
|
||||||
0, // static table
|
0, // static table
|
||||||
loader,
|
loader,
|
||||||
|
0, // source
|
||||||
0);// vtable length
|
0);// vtable length
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
@ -3389,6 +3390,8 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_,
|
|||||||
(t, classLoaderMap(t, loader), spec, byteArrayHash, byteArrayEqual);
|
(t, classLoaderMap(t, loader), spec, byteArrayHash, byteArrayEqual);
|
||||||
|
|
||||||
if (class_ == 0) {
|
if (class_ == 0) {
|
||||||
|
PROTECT(t, class_);
|
||||||
|
|
||||||
if (classLoaderParent(t, loader)) {
|
if (classLoaderParent(t, loader)) {
|
||||||
class_ = resolveSystemClass
|
class_ = resolveSystemClass
|
||||||
(t, classLoaderParent(t, loader), spec, false);
|
(t, classLoaderParent(t, loader), spec, false);
|
||||||
@ -3430,6 +3433,20 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_,
|
|||||||
class_);
|
class_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ const char* source = static_cast<Finder*>
|
||||||
|
(systemClassLoaderFinder(t, loader))->sourceUrl
|
||||||
|
(RUNTIME_ARRAY_BODY(file));
|
||||||
|
|
||||||
|
if (source) {
|
||||||
|
unsigned length = strlen(source);
|
||||||
|
object array = makeByteArray(t, length + 1);
|
||||||
|
memcpy(&byteArrayBody(t, array, 0), source, length);
|
||||||
|
array = internByteArray(t, array);
|
||||||
|
|
||||||
|
set(t, class_, ClassSource, array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object bootstrapClass = hashMapFind
|
object bootstrapClass = hashMapFind
|
||||||
(t, root(t, Machine::BootstrapClassMap), spec, byteArrayHash,
|
(t, root(t, Machine::BootstrapClassMap), spec, byteArrayHash,
|
||||||
byteArrayEqual);
|
byteArrayEqual);
|
||||||
@ -3444,8 +3461,6 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (class_) {
|
if (class_) {
|
||||||
PROTECT(t, class_);
|
|
||||||
|
|
||||||
hashMapInsert(t, classLoaderMap(t, loader), spec, class_, byteArrayHash);
|
hashMapInsert(t, classLoaderMap(t, loader), spec, class_, byteArrayHash);
|
||||||
} else if (throw_) {
|
} else if (throw_) {
|
||||||
throwNew(t, throwType, "%s", &byteArrayBody(t, spec, 0));
|
throwNew(t, throwType, "%s", &byteArrayBody(t, spec, 0));
|
||||||
|
Reference in New Issue
Block a user