1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import java.lang.reflect.*; 18 19 public class Main { 20 public static final String TEST_NAME = "998-redefine-use-after-free"; 21 public static final int REPS = 1000; 22 public static final int STEP = 100; 23 main(String[] args)24 public static void main(String[] args) throws Exception { 25 for (int i = 0; i < REPS; i += STEP) { 26 runSeveralTimes(STEP); 27 } 28 } 29 getClassLoaderFor(String location)30 public static ClassLoader getClassLoaderFor(String location) throws Exception { 31 try { 32 Class<?> class_loader_class = Class.forName("dalvik.system.PathClassLoader"); 33 Constructor<?> ctor = class_loader_class.getConstructor(String.class, ClassLoader.class); 34 return (ClassLoader)ctor.newInstance(location + "/" + TEST_NAME + "-ex.jar", 35 Main.class.getClassLoader()); 36 } catch (ClassNotFoundException e) { 37 // Running on RI. Use URLClassLoader. 38 return new java.net.URLClassLoader( 39 new java.net.URL[] { new java.net.URL("file://" + location + "/classes-ex/") }); 40 } 41 } 42 43 // Run the redefinition several times on a single class-loader to try to trigger the 44 // Use-after-free bug b/62237378 runSeveralTimes(int times)45 public static void runSeveralTimes(int times) throws Exception { 46 ClassLoader c = getClassLoaderFor(System.getenv("DEX_LOCATION")); 47 48 Class<?> klass = (Class<?>)c.loadClass("DexCacheSmash"); 49 Method m = klass.getDeclaredMethod("run"); 50 for (int i = 0 ; i < times; i++) { 51 m.invoke(null); 52 } 53 } 54 } 55