We've
had security manager checks in the reflection code in Jikes RVM for a while.
Our current workaround for serialization is that classes loaded by
the system classloader are always allowed access. This is probably
too big of a hole, but it does work in practice. The key routine
for us is in java.lang.reflect.JikesRVMSupport (appended below).
If you come up with a finer-grained fix for libgcj, let me know -- I'm
not that happy with what we are currently doing in Jikes RVM.
--dave
/**
* Check to see if a method declared by the accessingClass
* should be allowed to access the argument VM_Member.
* Assumption: member is not public. This trivial case should
* be approved by the caller without needing to call this method.
*/
public static void checkAccess(VM_Member member, VM_Class accessingClass)
throws IllegalAccessException {
// TODO: Is this the right kludge?
// We must allow classes like java.io.ObjectOutputStream
access to anything.
// Allowing everything loaded by the system classloader the
same freedom
// might be too broad of a loophole.
if (accessingClass.getClassLoader() == VM_SystemClassLoader.getVMClassLoader())
return;
VM_Class declaringClass = member.getDeclaringClass();
if (member.isPrivate()) {
// access from the declaringClass is allowed
if (accessingClass == declaringClass) return;
} else if (member.isProtected()) {
// access within the package is allowed.
if (declaringClass.getPackageName().equals(accessingClass.getPackageName()))
return;
// access by subclasses is allowed.
for (VM_Class cls = accessingClass; cls != null; cls
= cls.getSuperClass()) {
if (accessingClass == declaringClass) return;
}
} else {
// default: access within package is allowed
if (declaringClass.getPackageName().equals(accessingClass.getPackageName()))
return;
}
throw new IllegalAccessException("Access to "+member+"
is denied to "+accessingClass);
}