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:
Joel Dice 2011-03-31 19:16:57 -06:00
parent 8d9412c1e8
commit 1c7abe782d
10 changed files with 120 additions and 17 deletions

View File

@ -10,14 +10,28 @@
package avian;
import java.net.URL;
import java.net.MalformedURLException;
import java.security.CodeSource;
import java.security.AllPermission;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
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();
p.add(new AllPermission());
return new ProtectionDomain(null, p);
return new ProtectionDomain(source, p);
}
}

View File

@ -25,7 +25,8 @@ public class VMClass {
public VMMethod[] virtualTable;
public VMField[] fieldTable;
public VMMethod[] methodTable;
public avian.ClassAddendum addendum;
public ClassAddendum addendum;
public Object staticTable;
public ClassLoader loader;
public byte[] source;
}

View File

@ -10,4 +10,17 @@
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;
}
}

View 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 { }

View File

@ -3667,22 +3667,25 @@ EXPORT(JVM_SetClassSigners)(Thread* t, jclass c, jobjectArray signers)
}
uint64_t
jvmGetProtectionDomain(Thread* t, uintptr_t*)
jvmGetProtectionDomain(Thread* t, uintptr_t* arguments)
{
object openJDK = resolveClass
(t, root(t, Machine::BootLoader), "avian/OpenJDK");
jclass c = reinterpret_cast<jclass>(arguments[0]);
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>
(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
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

View File

@ -8234,8 +8234,8 @@ class MyProcessor: public Processor {
{
return vm::makeClass
(t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions,
0, objectMask, name, sourceFile, super, interfaceTable,
virtualTable, fieldTable, methodTable, staticTable, addendum, loader,
0, objectMask, name, sourceFile, super, interfaceTable, virtualTable,
fieldTable, methodTable, staticTable, addendum, loader, 0,
vtableLength);
}

View File

@ -32,6 +32,17 @@ append(Allocator* allocator, const char* a, const char* b, const char* c)
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*
copy(Allocator* allocator, const char* a)
{
@ -56,6 +67,7 @@ class Element {
virtual System::FileType stat(const char* name, unsigned* length,
bool tryDirectory) = 0;
virtual const char* urlPrefix() = 0;
virtual const char* sourceUrl() = 0;
virtual void dispose() = 0;
Element* next;
@ -125,7 +137,8 @@ class DirectoryElement: public Element {
DirectoryElement(System* s, Allocator* allocator, const char* 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() {
@ -163,9 +176,14 @@ class DirectoryElement: public Element {
return urlPrefix_;
}
virtual const char* sourceUrl() {
return sourceUrl_;
}
virtual void dispose() {
allocator->free(name, strlen(name) + 1);
allocator->free(urlPrefix_, strlen(urlPrefix_) + 1);
allocator->free(sourceUrl_, strlen(sourceUrl_) + 1);
allocator->free(this, sizeof(*this));
}
@ -173,6 +191,7 @@ class DirectoryElement: public Element {
Allocator* allocator;
const char* name;
const char* urlPrefix_;
const char* sourceUrl_;
};
class PointerRegion: public System::Region {
@ -438,6 +457,7 @@ class JarElement: public Element {
JarElement(System* s, Allocator* allocator, const char* name):
s(s), allocator(allocator), name(name),
urlPrefix_(name ? append(allocator, "jar:file:", name, "!/") : 0),
sourceUrl_(name ? append(allocator, "file:", name) : 0),
region(0), index(0)
{ }
@ -447,6 +467,7 @@ class JarElement: public Element {
allocator(allocator),
name(0),
urlPrefix_(name ? append(allocator, "jar:file:", name, "!/") : 0),
sourceUrl_(name ? append(allocator, "file:", name) : 0),
region(new (allocator->allocate(sizeof(PointerRegion)))
PointerRegion(s, allocator, jarData, jarLength)),
index(JarIndex::open(s, allocator, region))
@ -500,6 +521,10 @@ class JarElement: public Element {
return urlPrefix_;
}
virtual const char* sourceUrl() {
return sourceUrl_;
}
virtual void dispose() {
dispose(sizeof(*this));
}
@ -507,6 +532,7 @@ class JarElement: public Element {
virtual void dispose(unsigned size) {
allocator->free(name, strlen(name) + 1);
allocator->free(urlPrefix_, strlen(urlPrefix_) + 1);
allocator->free(sourceUrl_, strlen(sourceUrl_) + 1);
if (index) {
index->dispose();
}
@ -520,6 +546,7 @@ class JarElement: public Element {
Allocator* allocator;
const char* name;
const char* urlPrefix_;
const char* sourceUrl_;
System::Region* region;
JarIndex* index;
};
@ -556,6 +583,10 @@ class BuiltinElement: public JarElement {
return "resource:";
}
virtual const char* sourceUrl() {
return 0;
}
virtual void dispose() {
library->disposeAll();
if (libraryName) {
@ -802,6 +833,18 @@ class MyFinder: public Finder {
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() {
return pathString;
}

View File

@ -168,6 +168,7 @@ class Finder {
unsigned* length,
bool tryDirectory = false) = 0;
virtual const char* urlPrefix(const char* name) = 0;
virtual const char* sourceUrl(const char* name) = 0;
virtual const char* path() = 0;
virtual void dispose() = 0;
};

View File

@ -2982,7 +2982,7 @@ class MyProcessor: public Processor {
return vm::makeClass
(t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions, 0,
objectMask, name, sourceFile, super, interfaceTable, virtualTable,
fieldTable, methodTable, addendum, staticTable, loader, 0);
fieldTable, methodTable, addendum, staticTable, loader, 0, 0);
}
virtual void

View File

@ -3320,6 +3320,7 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size,
0, // addendum
0, // static table
loader,
0, // source
0);// vtable length
PROTECT(t, class_);
@ -3389,6 +3390,8 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_,
(t, classLoaderMap(t, loader), spec, byteArrayHash, byteArrayEqual);
if (class_ == 0) {
PROTECT(t, class_);
if (classLoaderParent(t, loader)) {
class_ = resolveSystemClass
(t, classLoaderParent(t, loader), spec, false);
@ -3430,6 +3433,20 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_,
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
(t, root(t, Machine::BootstrapClassMap), spec, byteArrayHash,
byteArrayEqual);
@ -3444,8 +3461,6 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_,
}
if (class_) {
PROTECT(t, class_);
hashMapInsert(t, classLoaderMap(t, loader), spec, class_, byteArrayHash);
} else if (throw_) {
throwNew(t, throwType, "%s", &byteArrayBody(t, spec, 0));