From: Rahmadi Trimananda Date: Fri, 28 Jun 2019 01:18:50 +0000 (-0700) Subject: Adding recursive call to the getResolvedClassInfo() method: look into the parent... X-Git-Url: http://plrg.eecs.uci.edu/git/?p=jpf-core.git;a=commitdiff_plain;h=cb320aaa4dee0e89ab89e207f7102e9db648773a Adding recursive call to the getResolvedClassInfo() method: look into the parent (SystemClassLoaderInfo); adding the ProtectionDomain and AllPermission classes. --- diff --git a/examples/Reflection.java b/examples/Reflection.java index cc13e07..9502a04 100644 --- a/examples/Reflection.java +++ b/examples/Reflection.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.math.BigInteger; +import java.security.ProtectionDomain; public class Reflection { @@ -79,8 +80,9 @@ public class Reflection { Type returnType = method.getGenericReturnType(); Class.class.getSimpleName();*/ //System.out.println(returnType); - BigInteger bi = new BigInteger("-1"); - System.out.println(bi); + + //BigInteger bi = new BigInteger("-1"); + //System.out.println(bi); /* TODO: This is an excerpt of the BigInteger library int radix = 10; @@ -178,7 +180,7 @@ public class Reflection { System.out.println(returnType);*/ /* TODO: Enumerate all methods in Class.class */ - Method[] methods = Class.class.getMethods(); + /*Method[] methods = Class.class.getMethods(); for(Method mth : methods) { System.out.println("==========================="); System.out.println("Method: " + mth.getName()); @@ -189,7 +191,7 @@ public class Reflection { System.out.println(); Type returnType = mth.getGenericReturnType(); System.out.println(returnType + "\n"); - } + }*/ /*Class[] parameterTypes = methods[0].getParameterTypes(); for(Class parameterType: parameterTypes){ @@ -210,6 +212,9 @@ public class Reflection { System.out.println(bound); } System.out.println();*/ + + ProtectionDomain pd = Class.class.getProtectionDomain(); + System.out.println(pd); } } diff --git a/src/classes/java/lang/Class.java b/src/classes/java/lang/Class.java index 3d21d02..7dd3947 100644 --- a/src/classes/java/lang/Class.java +++ b/src/classes/java/lang/Class.java @@ -330,10 +330,12 @@ public final class Class implements Serializable, GenericDeclaration, Type, A public Class[] getDeclaredClasses() throws SecurityException { throw new UnsupportedOperationException(); } - - public java.security.ProtectionDomain getProtectionDomain() { + + // TODO: Fix for Groovy's model-checking + public native java.security.ProtectionDomain getProtectionDomain(); + /*public java.security.ProtectionDomain getProtectionDomain() { throw new UnsupportedOperationException(); - } + }*/ void setProtectionDomain0(java.security.ProtectionDomain pd) { pd = null; // Get rid of IDE warning diff --git a/src/classes/java/security/AllPermission.java b/src/classes/java/security/AllPermission.java new file mode 100644 index 0000000..658c063 --- /dev/null +++ b/src/classes/java/security/AllPermission.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * The Java Pathfinder core (jpf-core) platform is licensed under the + * Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package java.security; + +import java.util.Enumeration; +import sun.security.util.SecurityConstants; + +// TODO: Fix for Groovy's model-checking +/** + * MJI model class for java.security.AllPermission library abstraction + */ +public final class AllPermission extends Permission { + + private static final long serialVersionUID = -2916474571451318075L; + + public AllPermission() { + super(""); + } + + public boolean implies(Permission p) { + return true; + } + + public boolean equals(Object obj) { + return (obj instanceof AllPermission); + } + + public int hashCode() { + return 1; + } + + public String getActions() { + return ""; + } + + public PermissionCollection newPermissionCollection() { + return new AllPermissionCollection(); + } + +} + + +final class AllPermissionCollection + extends PermissionCollection + implements java.io.Serializable +{ + + // use serialVersionUID from JDK 1.2.2 for interoperability + private static final long serialVersionUID = -4023755556366636806L; + + private boolean all_allowed; // true if any all permissions have been added + + public AllPermissionCollection() { + all_allowed = false; + } + + public void add(Permission permission) { + if (! (permission instanceof AllPermission)) + throw new IllegalArgumentException("invalid permission: "+ + permission); + if (isReadOnly()) + throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection"); + + all_allowed = true; // No sync; staleness OK + } + + public boolean implies(Permission permission) { + return all_allowed; // No sync; staleness OK + } + + public Enumeration elements() { + return new Enumeration() { + private boolean hasMore = all_allowed; + + public boolean hasMoreElements() { + return hasMore; + } + + public Permission nextElement() { + hasMore = false; + return SecurityConstants.ALL_PERMISSION; + } + }; + } +} diff --git a/src/classes/java/security/ProtectionDomain.java b/src/classes/java/security/ProtectionDomain.java new file mode 100644 index 0000000..09650ab --- /dev/null +++ b/src/classes/java/security/ProtectionDomain.java @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * The Java Pathfinder core (jpf-core) platform is licensed under the + * Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package java.security; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import sun.security.util.Debug; +import sun.security.util.SecurityConstants; + +// TODO: Fix for Groovy's model-checking +/** + * MJI model class for java.security.ProtectionDomain library abstraction + */ +public class ProtectionDomain { + + private CodeSource codesource ; + + private ClassLoader classloader; + + private Principal[] principals; + + private PermissionCollection permissions; + + private boolean hasAllPerm = false; + + private boolean staticPermissions; + + final Key key = new Key(); + + private Debug debug = Debug.getInstance("domain"); + + public ProtectionDomain(CodeSource codesource, + PermissionCollection permissions) { + this.codesource = codesource; + if (permissions != null) { + this.permissions = permissions; + this.permissions.setReadOnly(); + if (permissions instanceof Permissions && + ((Permissions)permissions).allPermission != null) { + hasAllPerm = true; + } + } + this.classloader = null; + this.principals = new Principal[0]; + staticPermissions = true; + } + + public ProtectionDomain(CodeSource codesource, + PermissionCollection permissions, + ClassLoader classloader, + Principal[] principals) { + this.codesource = codesource; + if (permissions != null) { + this.permissions = permissions; + this.permissions.setReadOnly(); + if (permissions instanceof Permissions && + ((Permissions)permissions).allPermission != null) { + hasAllPerm = true; + } + } + this.classloader = classloader; + this.principals = (principals != null ? principals.clone(): + new Principal[0]); + staticPermissions = false; + } + + public final CodeSource getCodeSource() { + return this.codesource; + } + + public final ClassLoader getClassLoader() { + return this.classloader; + } + + public final Principal[] getPrincipals() { + return this.principals.clone(); + } + + public final PermissionCollection getPermissions() { + return permissions; + } + + public boolean implies(Permission permission) { + + if (hasAllPerm) { + // internal permission collection already has AllPermission - + // no need to go to policy + return true; + } + + if (!staticPermissions && + Policy.getPolicyNoCheck().implies(this, permission)) + return true; + if (permissions != null) + return permissions.implies(permission); + + return false; + } + + boolean impliesCreateAccessControlContext() { + return implies(SecurityConstants.CREATE_ACC_PERMISSION); + } + + @Override public String toString() { + String pals = ""; + if (principals != null && principals.length > 0) { + StringBuilder palBuf = new StringBuilder("(principals "); + + for (int i = 0; i < principals.length; i++) { + palBuf.append(principals[i].getClass().getName() + + " \"" + principals[i].getName() + + "\""); + if (i < principals.length-1) + palBuf.append(",\n"); + else + palBuf.append(")\n"); + } + pals = palBuf.toString(); + } + + // Check if policy is set; we don't want to load + // the policy prematurely here + PermissionCollection pc = Policy.isSet() && seeAllp() ? + mergePermissions(): + getPermissions(); + + return "ProtectionDomain "+ + " "+codesource+"\n"+ + " "+classloader+"\n"+ + " "+pals+"\n"+ + " "+pc+"\n"; + } + + private boolean seeAllp() { + SecurityManager sm = System.getSecurityManager(); + + if (sm == null) { + return true; + } else { + if (debug != null) { + if (sm.getClass().getClassLoader() == null && + Policy.getPolicyNoCheck().getClass().getClassLoader() + == null) { + return true; + } + } else { + try { + sm.checkPermission(SecurityConstants.GET_POLICY_PERMISSION); + return true; + } catch (SecurityException se) { + // fall thru and return false + } + } + } + + return false; + } + + private PermissionCollection mergePermissions() { + if (staticPermissions) + return permissions; + + PermissionCollection perms = + java.security.AccessController.doPrivileged + (new java.security.PrivilegedAction() { + public PermissionCollection run() { + Policy p = Policy.getPolicyNoCheck(); + return p.getPermissions(ProtectionDomain.this); + } + }); + + Permissions mergedPerms = new Permissions(); + int swag = 32; + int vcap = 8; + Enumeration e; + List pdVector = new ArrayList<>(vcap); + List plVector = new ArrayList<>(swag); + + // + // Build a vector of domain permissions for subsequent merge + if (permissions != null) { + synchronized (permissions) { + e = permissions.elements(); + while (e.hasMoreElements()) { + pdVector.add(e.nextElement()); + } + } + } + + // + // Build a vector of Policy permissions for subsequent merge + if (perms != null) { + synchronized (perms) { + e = perms.elements(); + while (e.hasMoreElements()) { + plVector.add(e.nextElement()); + vcap++; + } + } + } + + if (perms != null && permissions != null) { + // + // Weed out the duplicates from the policy. Unless a refresh + // has occurred since the pd was consed this should result in + // an empty vector. + synchronized (permissions) { + e = permissions.elements(); // domain vs policy + while (e.hasMoreElements()) { + Permission pdp = e.nextElement(); + Class pdpClass = pdp.getClass(); + String pdpActions = pdp.getActions(); + String pdpName = pdp.getName(); + for (int i = 0; i < plVector.size(); i++) { + Permission pp = plVector.get(i); + if (pdpClass.isInstance(pp)) { + // The equals() method on some permissions + // have some side effects so this manual + // comparison is sufficient. + if (pdpName.equals(pp.getName()) && + pdpActions.equals(pp.getActions())) { + plVector.remove(i); + break; + } + } + } + } + } + } + + if (perms !=null) { + // the order of adding to merged perms and permissions + // needs to preserve the bugfix 4301064 + + for (int i = plVector.size()-1; i >= 0; i--) { + mergedPerms.add(plVector.get(i)); + } + } + if (permissions != null) { + for (int i = pdVector.size()-1; i >= 0; i--) { + mergedPerms.add(pdVector.get(i)); + } + } + + return mergedPerms; + } + + final class Key {} +} \ No newline at end of file diff --git a/src/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java b/src/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java index ad0bca9..ac627a0 100644 --- a/src/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java +++ b/src/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * The Java Pathfinder core (jpf-core) platform is licensed under the + * Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package sun.reflect.generics.reflectiveObjects; import java.lang.reflect.GenericArrayType; diff --git a/src/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java b/src/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java index 809dbf4..48c30d2 100644 --- a/src/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java +++ b/src/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * The Java Pathfinder core (jpf-core) platform is licensed under the + * Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package sun.reflect.generics.reflectiveObjects; import sun.reflect.generics.tree.FieldTypeSignature; diff --git a/src/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java b/src/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java index a10eb87..ebe6114 100644 --- a/src/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java +++ b/src/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * The Java Pathfinder core (jpf-core) platform is licensed under the + * Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package sun.reflect.generics.reflectiveObjects; import java.lang.annotation.*; diff --git a/src/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java b/src/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java index 5a4fdaf..4a2933c 100644 --- a/src/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java +++ b/src/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java @@ -1,6 +1,22 @@ +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * The Java Pathfinder core (jpf-core) platform is licensed under the + * Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package sun.reflect.generics.reflectiveObjects; - import java.lang.reflect.Type; import java.lang.reflect.WildcardType; import sun.reflect.generics.factory.GenericsFactory; diff --git a/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java b/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java index dec2423..63c3c88 100644 --- a/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java +++ b/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java @@ -351,16 +351,22 @@ public class ClassLoaderInfo try { log.info("loading class ", typeName, " from ", url); ci = match.createClassInfo(this); - + } catch (ClassParseException cpx){ throw new ClassInfoException( "error parsing class", this, "java.lang.NoClassDefFoundError", typeName, cpx); } - + loadedClasses.put( url, ci); } - + } else { // no match found - throw new ClassInfoException("class not found: " + typeName, this, "java.lang.ClassNotFoundException", typeName); + // TODO: Fix for Groovy's model-checking + // TODO: May need to do a recursive lookup + if (parent != null) { + return parent.getResolvedClassInfo(typeName); + } else { + throw new ClassInfoException("class not found: " + typeName, this, "java.lang.ClassNotFoundException", typeName); + } } } diff --git a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java index 2c769f2..20c59e8 100644 --- a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java +++ b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java @@ -161,6 +161,7 @@ public class JPF_java_lang_Class extends NativePeer { return typeVarRef; } + // TODO: Fix for Groovy's model-checking @MJI public int getGenericSuperclass____Ljava_lang_reflect_Type_2 (MJIEnv env, int robj){ ClassInfo ci = env.getReferredClassInfo( robj); @@ -242,6 +243,32 @@ public class JPF_java_lang_Class extends NativePeer { return aRef; } + + @MJI + public int getProtectionDomain____Ljava_security_ProtectionDomain_2 (MJIEnv env, int robj) { + // Now create a ProtectionDomain object + ClassLoaderInfo cli = env.getSystemClassLoaderInfo(); + ClassInfo pdci = cli.getResolvedClassInfo("java.security.ProtectionDomain"); + + int proDomRef = MJIEnv.NULL; + /* TODO: Defer the following to future implementations + int proDomRef = env.newObject(pdci); + ElementInfo ei = env.getModifiableElementInfo(proDomRef); + ei.setReferenceField("codesource", MJIEnv.NULL); + ei.setReferenceField("classloader", MJIEnv.NULL); + ei.setBooleanField("hasAllPerm", true); + ei.setBooleanField("staticPermissions", true); + + // Load the Permission (AllPermission class) + ClassInfo pci = cli.getResolvedClassInfo("java.security.AllPermission"); + int permRef = env.newObject(pci); + ElementInfo pei = env.getModifiableElementInfo(permRef); + pei.setReferenceField("name", env.newString("")); + ei.setReferenceField("permissions", permRef);*/ + + return proDomRef; + } + // TODO: Fix for Groovy's model-checking @MJI public int getAnnotation__Ljava_lang_Class_2__Ljava_lang_annotation_Annotation_2 (MJIEnv env, int robj, diff --git a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java index 136c12e..98a8dd4 100644 --- a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java +++ b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java @@ -144,7 +144,6 @@ public class JPF_java_lang_ClassLoader extends NativePeer { byte[] buffer = env.getByteArrayObject(bufferRef); try { - ClassInfo ci = cl.getResolvedClassInfo( cname, buffer, offset, length); // Note: if the representation is not of a supported major or minor version, loading