Commit 74b30bf8 authored by John Zhang's avatar John Zhang

WIP: fixing daytrader/geronimo SUID bug

- added SUIDBugFixingAgent code
- added some flags in build to skip geronimo build
- stuck on a mysterious ClassNotFoundException
parent ffbd9389
Pipeline #2949 passed with stage
in 22 minutes and 51 seconds
......@@ -108,7 +108,7 @@
<target name="pre-build" depends="clean, init, unpack"/>
<target name="clean">
<target name="clean" unless="bm-common-no-clean">
<delete dir="${bm-output-dir}"/>
<delete dir="${bm-build-dir}"/>
<delete dir="${bm-deps-output-dir}"/>
......
benchmark tradebeans
class org.dacapo.harness.Tradebeans
thread-model per_cpu
jars "daytrader.jar";
jars "daytrader.jar", "asm-6.2.jar", "asm-commons-6.2.jar", "tools.jar";
size small args "tiny"
threads 1 // per available processor
......
......@@ -350,7 +350,7 @@ See ${log.build.report} for a summary of benchmark build status.
<echo level="error" message="build: PASS${line.separator}"/>
<echo file="${log.build.pass}" level="error" message="build: PASS${line.separator}"/>
</target>
<property name="ant-bm-build-args" value=""/>
<macrodef name="build.bm">
<attribute name="benchmark"/>
<sequential>
......@@ -361,6 +361,7 @@ See ${log.build.report} for a summary of benchmark build status.
<arg value="-Dbuild.target-jar=${build.target-jar}"/>
<arg value="-buildfile"/>
<arg value="bms/@{benchmark}/build.xml"/>
<arg line="${ant-bm-build-args}"/>
<arg value="incremental"/>
</exec>
<condition property="@{benchmark}.failed">
......
......@@ -57,7 +57,7 @@
<target name="pre-build" depends="clean, init, unpack"/>
<target name="clean">
<target name="clean" unless="lib-common-no-clean">
<delete dir="${lib-output-dir}"/>
<delete dir="${lib-build-dir}"/>
</target>
......
......@@ -48,6 +48,15 @@
<property name="servicemix-bundles-url" value="${maven-central}/${servicemix-bundles-groupId}"/>
<property name="servicemix-bundles-bin" value="org.apache.servicemix.bundles.dom4j-${servicemix-bundles-version}.jar"/>
<property name="ow2-asm-version" value="6.2"/>
<property name="ow2-asm-groupId" value="org/ow2/asm/asm/${ow2-asm-version}"/>
<property name="ow2-asm-url" value="${maven-central}/${ow2-asm-groupId}"/>
<property name="ow2-asm-bin" value="asm-${ow2-asm-version}.jar"/>
<property name="ow2-asm-commons-groupId" value="org/ow2/asm/asm-commons/${ow2-asm-version}"/>
<property name="ow2-asm-commons-url" value="${maven-central}/${ow2-asm-commons-groupId}"/>
<property name="ow2-asm-commons-bin" value="asm-commons-${ow2-asm-version}.jar"/>
<property name="sun-tools-jar" value="${java.home}/../lib/tools.jar"/>
<import file="../common.xml"/>
......@@ -60,6 +69,8 @@
<property name="ger-kernel-jar" value="${ger-home}/repository/org/apache/geronimo/framework/geronimo-kernel/${ger-version}/geronimo-kernel-${ger-version}.jar"/>
<property name="osgi-framework-util-jar" value="${ger-home}/repository/org/osgi/org.osgi.core/4.3.1/org.osgi.core-4.3.1.jar"/>
<property name="geronimo-main-jar" value="${ger-home}/lib/geronimo-main.jar"/>
<property name="ow2-asm-jar" value="${lib-downloads}/${ow2-asm-bin}"/>
<property name="ow2-asm-commons-jar" value="${lib-downloads}/${ow2-asm-commons-bin}"/>
<condition property="shell-exe" value="cmd.exe">
<os family="windows"/>
......@@ -79,7 +90,7 @@
<property name="mvn-exe" value="mvn"/>
<target name="url-source" if="ger-url">
<target name="url-source" if="ger-url" unless="lib-daytrader-no-url-source">
<antcall target="check-source">
<param name="target-dir" value="${lib-downloads}"/>
<param name="target-url" value="${ger-url}"/>
......@@ -106,6 +117,16 @@
<param name="target-url" value="${servicemix-bundles-url}"/>
<param name="target-file" value="${servicemix-bundles-bin}"/>
</antcall>
<antcall target="check-source">
<param name="target-dir" value="${lib-downloads}"/>
<param name="target-url" value="${ow2-asm-url}"/>
<param name="target-file" value="${ow2-asm-bin}"/>
</antcall>
<antcall target="check-source">
<param name="target-dir" value="${lib-downloads}"/>
<param name="target-url" value="${ow2-asm-commons-url}"/>
<param name="target-file" value="${ow2-asm-commons-bin}"/>
</antcall>
</target>
<target name="unpack">
......@@ -137,17 +158,25 @@
</target>
<target name="jar" depends="build">
<target name="jar" depends="build,data">
<jar destfile="${lib-jars}/${lib-name}.jar">
<fileset dir="${launcher-build}">
<include name="**/*.class"/>
</fileset>
<manifest>
<attribute name="Agent-Class" value="org.dacapo.daytrader.SUIDBugFixAgent"/>
</manifest>
</jar>
<copy file="${ow2-asm-jar}" todir="${lib-jars}"/>
<copy file="${ow2-asm-commons-jar}" todir="${lib-jars}"/>
<copy file="${sun-tools-jar}" todir="${lib-jars}"/>
</target>
<target name="build" depends="build.init,data">
<target name="build" depends="build.init">
<mkdir dir="${launcher-build}/"/>
<javac srcdir="${lib-src-dir}" destdir="${launcher-build}" classpath="${ger-cli-jar}:${ger-kernel-jar}:${osgi-framework-util-jar}:${geronimo-main-jar}" debug="true" debuglevel="lines,vars,source"/>
<javac srcdir="${lib-src-dir}" destdir="${launcher-build}"
classpath="${ger-cli-jar}:${ger-kernel-jar}:${osgi-framework-util-jar}:${geronimo-main-jar}:${ow2-asm-jar}:${ow2-asm-commons-jar}"
debug="true" debuglevel="lines,vars,source"/>
</target>
<target name="build.init">
......@@ -155,8 +184,7 @@
<property name="mvn" location="${mvn-home}/${mvn-exe}"/>
</target>
<target name="data" depends="build.init">
<target name="geronimo-build" unless="lib-daytrader-skip-geronimo-build">
<!-- build required plugins -->
<exec executable="${mvn}" dir="${lib-build-dir}/plugins/client" failonerror="yes" failifexecutionfails="yes">
<arg value="-Dmaven.test.skip=true"/>
......@@ -215,8 +243,9 @@
</antcall>
<antcall target="stop-geronimo"/>
</target>
<target name="data" depends="build.init, geronimo-build">
<!-- hack to get geronimo to correctly load RMIClassLoaderSpiImpl
which it only seems to load from the jar that dacapo is contained in -->
<unjar src="${lib-build-dir}/${ger-name}-${ger-version}/lib/geronimo-rmi-loader.jar" dest="${bm-output-dir}">
......@@ -291,4 +320,10 @@
<arg value="${deploy-subject}"/>
</exec>
</target>
<target name="add-agentmain-to-manifest">
<manifest file="${basedir}/src/META-INF/MANIFEST.MF" mode="update">
<attribute name="Agent-Class" value="org.dacapo.daytrader.SUIDBugFixAgent"/>
</manifest>
</target>
</project>
package org.dacapo.daytrader;
public class DummyClass {
public static void someStaticMethod() {
System.out.println("[org.dacapo.daytrader.DummyClass] someStaticMethod() invoked.");
}
public void someInstMethod() {
System.out.println("[org.dacapo.daytrader.DummyClass] someInstMethod() invoked.");
}
}
\ No newline at end of file
......@@ -59,12 +59,37 @@ public class Launcher {
ClassLoader originalCLoader = Thread.currentThread().getContextClassLoader();
try {
// Issue #23:
// Loading agent ultimately causes the ClassNotFoundException throw below.
// Why is that? The agent is not doing anything in particular (just printing out a message).
SUIDBugFixAgent.loadAgent();
// Create a server environment
serverCLoader = createGeronimoClassLoader(originalCLoader, true);
Thread.currentThread().setContextClassLoader(serverCLoader);
SUIDBugFixAgent.printURLClassPaths((URLClassLoader)Thread.currentThread().getContextClassLoader());
Class<?> clazz = serverCLoader.loadClass("org.dacapo.daytrader.DaCapoServerRunner");
Method method = clazz.getMethod("initialize", new Class[] {});
method.invoke(null, new Object[] {});
// Issue #23:
// This is to test whether invoking a static method from a class in the same package using reflection
// will cause the ClassNotFoundException.
// The test result suggests that it doesn't cause any trouble.
System.out.println("[Launcher] tryint to load org.dacapo.daytrader.DummyClass.someStaticMethod()");
Class<?> dummyClass = serverCLoader.loadClass("org.dacapo.daytrader.DummyClass");
Method dummyM = dummyClass.getMethod("someStaticMethod");
dummyM.invoke(null);
// Issue #23:
// No problem loading org.apache.geronimo.main.LaunchListener here.
Class<?> testClass = serverCLoader.loadClass("org.apache.geronimo.main.LaunchListener");
// Issue #23:
// A ClassNotFoundException got mysteriously thrown here.
// Why is getting org.dacapo.daytrader.DaCapoServerRunner.initialize()
// causes org.apache.geronimo.main.LaunchListener not found,
// when it **can** actually be found at line above?
Method method = clazz.getMethod("initialize");
method.invoke(null);
// Create a client environment
clientCLoader = createGeronimoClassLoader(originalCLoader, false);
......
package org.dacapo.daytrader;
import java.io.File;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URLClassLoader;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.NoSuchAlgorithmException;
import java.security.ProtectionDomain;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.lang.management.ManagementFactory;
import com.sun.tools.attach.VirtualMachine;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.SerialVersionUIDAdder;
class SUIDBugFixAgent {
public static void printURLClassPaths(URLClassLoader cl) {
System.out.println(Arrays.toString(cl.getURLs()));
}
private static File jarDayTrader;
private static URL[] AGENT_LIB_JARS;
static {
try {
jarDayTrader = new File(Launcher.class.getProtectionDomain().getCodeSource().getLocation().toURI());
File jarDir = jarDayTrader.getParentFile();
AGENT_LIB_JARS = new URL[] {
new URL("file:" + jarDir.getPath() + File.separator + "asm-6.2.jar"),
new URL("file:" + jarDir.getPath() + File.separator + "asm-commons-6.2.jar"),
new URL("file:" + jarDir.getPath() + File.separator + "tools.jar")
};
} catch (Exception e) {
e.printStackTrace();
}
}
public static void loadAgent() {
try {
String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
String pid = nameOfRunningVM.substring(0, nameOfRunningVM.indexOf('@'));
VirtualMachine vm = VirtualMachine.attach(pid);
vm.loadAgent(jarDayTrader.getPath(), null);
vm.detach();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void agentmain(String agentArgs, Instrumentation inst) {
System.out.println("[SUIDBugFixAgent] agentmain() invoked");
// // Hack to add ASM jars to system class loader path,
// // see [Java 7 Instrument](https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html),
// // section "Starting Agents After VM Startup", requirement 3.
// try {
// URLClassLoader sysCL = (URLClassLoader) ClassLoader.getSystemClassLoader();
// Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
// addURL.setAccessible(true);
// for (URL url : AGENT_LIB_JARS) {
// addURL.invoke(sysCL, url);
// }
// } catch (Exception e) {
// e.printStackTrace();
// System.exit(1);
// }
// printURLClassPaths((URLClassLoader)ClassLoader.getSystemClassLoader());
// // SUID bug fixing code
// inst.addTransformer(new ClassFileTransformer(){
// @Override
// public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
// ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
// if(!className.startsWith("org/apache/geronimo")) { // only care about org.apache.geronimo.*
// return classfileBuffer;
// }
// final ClassReader cr = new ClassReader(classfileBuffer);
// if((cr.getAccess() & Opcodes.ACC_INTERFACE) != 0) {
// return classfileBuffer;
// }
// /*
// * To completely fix this problem, precompute the serial UID based on old class members,
// * sidestepping the default serial UID computation which gets thrown off by new public members.
// */
// final ClassWriter cw = new ClassWriter(cr, 0);
// final SerialVersionUIDAdder adder = new SerialVersionUIDAdder(cw);
// cr.accept(adder, 0);
// return cw.toByteArray();
// }
// }, false);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment