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; 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);
} }
} }

View File

@ -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;
} }

View File

@ -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;
}
}

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 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

View File

@ -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);
} }

View File

@ -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;
} }

View File

@ -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;
}; };

View File

@ -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

View File

@ -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));