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