< prev index next >

test/hotspot/jtreg/runtime/verifier/CFLH/TestVerify.java

Print this page

 22  */
 23 
 24 /*
 25  * @test
 26  * @summary Verifier should verify ClassFileLoadHook bytes even if on bootclasspath
 27  * @bug 8351654
 28  * @requires vm.jvmti
 29  * @library /test/lib
 30  * @modules java.base/jdk.internal.misc
 31  * @modules java.compiler
 32  *          java.instrument
 33  *          jdk.jartool/sun.tools.jar
 34  * @compile TestChecker.java
 35  * @run driver jdk.test.lib.helpers.ClassFileInstaller checker/TestChecker
 36  * @run main TestVerify buildAgent
 37  * @run main/othervm --patch-module=java.base=. -Dagent.retransform=false -javaagent:redefineagent.jar TestVerify
 38  * @run main/othervm --patch-module=java.base=. -Dagent.retransform=true -javaagent:redefineagent.jar TestVerify
 39  */
 40 
 41 import java.lang.invoke.MethodHandles;
 42 import java.time.Duration;
 43 import java.lang.classfile.ClassFile;
 44 import java.lang.classfile.ClassTransform;
 45 import java.lang.classfile.MethodTransform;
 46 import java.lang.classfile.constantpool.InterfaceMethodRefEntry;
 47 import java.lang.classfile.instruction.ReturnInstruction;
 48 import java.lang.constant.ClassDesc;
 49 import java.lang.constant.ConstantDescs;
 50 import java.lang.constant.MethodTypeDesc;
 51 import java.lang.instrument.ClassFileTransformer;
 52 import java.lang.instrument.IllegalClassFormatException;
 53 import java.lang.instrument.Instrumentation;
 54 import java.nio.file.Files;
 55 import java.nio.file.Path;
 56 import java.security.ProtectionDomain;
 57 
 58 import java.io.PrintWriter;
 59 import jdk.test.lib.helpers.ClassFileInstaller;
 60 import java.io.FileNotFoundException;
 61 
 62 public class TestVerify {
 63 
 64     private static final String CLASS_TO_BREAK = "java.time.Duration";
 65     private static final String INTERNAL_CLASS_TO_BREAK = CLASS_TO_BREAK.replace('.', '/');
 66     private static final boolean DEBUG = false;
 67 
 68     private static class BadTransformer implements ClassFileTransformer {
 69 
 70         @Override
 71         public byte[] transform(Module module, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
 72 
 73             if (className.equals(INTERNAL_CLASS_TO_BREAK)) {
 74                 System.out.println("Instrumenting modular class " + INTERNAL_CLASS_TO_BREAK);
 75 
 76                 var methodTransform = MethodTransform.transformingCode((builder, element) -> {
 77                     if (element instanceof ReturnInstruction) {
 78                         System.out.println("Injecting bug");
 79                         // THE BUG! insert broken function call
 80 
 81                         var checkerDesc = ClassDesc.of("checker", "TestChecker");
 82                         builder.invokestatic(checkerDesc, "instance", MethodTypeDesc.of(checkerDesc), true);
 83 
 84                         // dup the instance ref, this is just to get a bad argument to the next method call
 85                         builder.dup();
 86 
 87                         // then call a check method that doesn't take that type, but we have the wrong desc
 88                         builder.invokeinterface(checkerDesc, "check", MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_Integer));
 89 
 90                         System.out.println("Done injecting bug");
 91                     }
 92                     builder.with(element);
 93                 });
 94                 var classTransform = ClassTransform.transformingMethods(mm -> mm.methodName().stringValue().equals("getSeconds"), methodTransform);
 95 
 96                 byte[] bytes;
 97                 try {
 98                     var cf = ClassFile.of();
 99                     var existingClass = cf.parse(classfileBuffer);
100                     bytes = cf.transformClass(existingClass, classTransform);
101 
102                     if (DEBUG) Files.write(Path.of("bad.class"), bytes);
103                 } catch (Throwable e) {
104                     throw new AssertionError(e);
105                 }
106                 return bytes;
107             }
108             return null;
109         }
110     }
111 
112     static Instrumentation inst = null;
113 
114     public static void premain(String args, Instrumentation instrumentation) throws Exception {

147         }
148 
149         // double check our class hasn't been loaded yet
150         for (Class clazz : inst.getAllLoadedClasses()) {
151             if (clazz.getName().equals(CLASS_TO_BREAK)) {
152                 throw new AssertionError("Oops! Class " + CLASS_TO_BREAK + " is already loaded, the test can't work");
153             }
154         }
155 
156         boolean retransform = Boolean.getBoolean("agent.retransform");
157 
158         try {
159             if (retransform) {
160                 // Retransform the class for the VerifyError.
161                 var clazz = Class.forName(CLASS_TO_BREAK);
162                 inst.addTransformer(new BadTransformer(), true);
163                 inst.retransformClasses(clazz);
164             } else {
165                 // Load the class instrumented with CFLH for the VerifyError.
166                 inst.addTransformer(new BadTransformer());
167                 System.out.println("1 hour is " + Duration.ofHours(1).getSeconds() + " seconds");

168             }
169             throw new RuntimeException("Failed: Did not throw VerifyError");
170         } catch (VerifyError e) {
171             System.out.println("Passed: VerifyError " + e.getMessage());
172         }
173     }
174 }

 22  */
 23 
 24 /*
 25  * @test
 26  * @summary Verifier should verify ClassFileLoadHook bytes even if on bootclasspath
 27  * @bug 8351654
 28  * @requires vm.jvmti
 29  * @library /test/lib
 30  * @modules java.base/jdk.internal.misc
 31  * @modules java.compiler
 32  *          java.instrument
 33  *          jdk.jartool/sun.tools.jar
 34  * @compile TestChecker.java
 35  * @run driver jdk.test.lib.helpers.ClassFileInstaller checker/TestChecker
 36  * @run main TestVerify buildAgent
 37  * @run main/othervm --patch-module=java.base=. -Dagent.retransform=false -javaagent:redefineagent.jar TestVerify
 38  * @run main/othervm --patch-module=java.base=. -Dagent.retransform=true -javaagent:redefineagent.jar TestVerify
 39  */
 40 
 41 import java.lang.invoke.MethodHandles;

 42 import java.lang.classfile.ClassFile;
 43 import java.lang.classfile.ClassTransform;
 44 import java.lang.classfile.MethodTransform;
 45 import java.lang.classfile.constantpool.InterfaceMethodRefEntry;
 46 import java.lang.classfile.instruction.ReturnInstruction;
 47 import java.lang.constant.ClassDesc;
 48 import java.lang.constant.ConstantDescs;
 49 import java.lang.constant.MethodTypeDesc;
 50 import java.lang.instrument.ClassFileTransformer;
 51 import java.lang.instrument.IllegalClassFormatException;
 52 import java.lang.instrument.Instrumentation;
 53 import java.nio.file.Files;
 54 import java.nio.file.Path;
 55 import java.security.ProtectionDomain;
 56 
 57 import java.io.PrintWriter;
 58 import jdk.test.lib.helpers.ClassFileInstaller;
 59 import java.io.FileNotFoundException;
 60 
 61 public class TestVerify {
 62 
 63     private static final String CLASS_TO_BREAK = "java.util.Date";
 64     private static final String INTERNAL_CLASS_TO_BREAK = CLASS_TO_BREAK.replace('.', '/');
 65     private static final boolean DEBUG = false;
 66 
 67     private static class BadTransformer implements ClassFileTransformer {
 68 
 69         @Override
 70         public byte[] transform(Module module, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
 71 
 72             if (className.equals(INTERNAL_CLASS_TO_BREAK)) {
 73                 System.out.println("Instrumenting modular class " + INTERNAL_CLASS_TO_BREAK);
 74 
 75                 var methodTransform = MethodTransform.transformingCode((builder, element) -> {
 76                     if (element instanceof ReturnInstruction) {
 77                         System.out.println("Injecting bug");
 78                         // THE BUG! insert broken function call
 79 
 80                         var checkerDesc = ClassDesc.of("checker", "TestChecker");
 81                         builder.invokestatic(checkerDesc, "instance", MethodTypeDesc.of(checkerDesc), true);
 82 
 83                         // dup the instance ref, this is just to get a bad argument to the next method call
 84                         builder.dup();
 85 
 86                         // then call a check method that doesn't take that type, but we have the wrong desc
 87                         builder.invokeinterface(checkerDesc, "check", MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_Integer));
 88 
 89                         System.out.println("Done injecting bug");
 90                     }
 91                     builder.with(element);
 92                 });
 93                 var classTransform = ClassTransform.transformingMethods(mm -> mm.methodName().stringValue().equals("parse"), methodTransform);
 94 
 95                 byte[] bytes;
 96                 try {
 97                     var cf = ClassFile.of();
 98                     var existingClass = cf.parse(classfileBuffer);
 99                     bytes = cf.transformClass(existingClass, classTransform);
100 
101                     if (DEBUG) Files.write(Path.of("bad.class"), bytes);
102                 } catch (Throwable e) {
103                     throw new AssertionError(e);
104                 }
105                 return bytes;
106             }
107             return null;
108         }
109     }
110 
111     static Instrumentation inst = null;
112 
113     public static void premain(String args, Instrumentation instrumentation) throws Exception {

146         }
147 
148         // double check our class hasn't been loaded yet
149         for (Class clazz : inst.getAllLoadedClasses()) {
150             if (clazz.getName().equals(CLASS_TO_BREAK)) {
151                 throw new AssertionError("Oops! Class " + CLASS_TO_BREAK + " is already loaded, the test can't work");
152             }
153         }
154 
155         boolean retransform = Boolean.getBoolean("agent.retransform");
156 
157         try {
158             if (retransform) {
159                 // Retransform the class for the VerifyError.
160                 var clazz = Class.forName(CLASS_TO_BREAK);
161                 inst.addTransformer(new BadTransformer(), true);
162                 inst.retransformClasses(clazz);
163             } else {
164                 // Load the class instrumented with CFLH for the VerifyError.
165                 inst.addTransformer(new BadTransformer());
166                 Class<?> cls = Class.forName(CLASS_TO_BREAK);
167                 System.out.println("class loaded" + cls);
168             }
169             throw new RuntimeException("Failed: Did not throw VerifyError");
170         } catch (VerifyError e) {
171             System.out.println("Passed: VerifyError " + e.getMessage());
172         }
173     }
174 }
< prev index next >