Skip to content

Commit

Permalink
[GR-28104] Use MD5 for checksums in serialization configs.
Browse files Browse the repository at this point in the history
PullRequest: graal/7839
  • Loading branch information
olpaw committed Dec 11, 2020
2 parents 565c2b3 + 9e00386 commit 72439a3
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@
import static com.oracle.svm.jvmtiagentbase.Support.getClassNameOr;
import static com.oracle.svm.jvmtiagentbase.Support.getClassNameOrNull;
import static com.oracle.svm.jvmtiagentbase.Support.getDirectCallerClass;
import static com.oracle.svm.jvmtiagentbase.Support.getObjectField;
import static com.oracle.svm.jvmtiagentbase.Support.getMethodDeclaringClass;
import static com.oracle.svm.jvmtiagentbase.Support.getObjectArgument;
import static com.oracle.svm.jvmtiagentbase.Support.getObjectField;
import static com.oracle.svm.jvmtiagentbase.Support.jniFunctions;
import static com.oracle.svm.jvmtiagentbase.Support.jvmtiEnv;
import static com.oracle.svm.jvmtiagentbase.Support.jvmtiFunctions;
Expand All @@ -54,6 +54,7 @@

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand All @@ -62,8 +63,6 @@
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.ReentrantLock;

import com.oracle.svm.util.SerializationChecksumCalculator;
import com.oracle.svm.jni.nativeapi.JNIFieldId;
import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.nativeimage.StackValue;
import org.graalvm.nativeimage.UnmanagedMemory;
Expand All @@ -85,6 +84,7 @@
import com.oracle.svm.core.c.function.CEntryPointOptions;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.jni.nativeapi.JNIEnvironment;
import com.oracle.svm.jni.nativeapi.JNIFieldId;
import com.oracle.svm.jni.nativeapi.JNIMethodId;
import com.oracle.svm.jni.nativeapi.JNINativeMethod;
import com.oracle.svm.jni.nativeapi.JNIObjectHandle;
Expand All @@ -100,6 +100,7 @@
import com.oracle.svm.jvmtiagentbase.jvmti.JvmtiEventMode;
import com.oracle.svm.jvmtiagentbase.jvmti.JvmtiFrameInfo;
import com.oracle.svm.jvmtiagentbase.jvmti.JvmtiLocationFormat;
import com.oracle.svm.util.SerializationChecksumCalculator;

/**
* Intercepts events of interest via breakpoints in Java code.
Expand Down Expand Up @@ -825,8 +826,8 @@ private static boolean findFieldHandle(JNIEnvironment jni, Breakpoint bp) {
}

static class CheckSumCalculator extends SerializationChecksumCalculator.JVMCIAgentCalculator {
private JNIEnvironment jni;
private Breakpoint bp;
private final JNIEnvironment jni;
private final Breakpoint bp;

CheckSumCalculator(JNIEnvironment jni, Breakpoint bp) {
this.jni = jni;
Expand Down Expand Up @@ -865,7 +866,7 @@ public String getClassName(WordBase clazz) {
private static boolean objectStreamClassConstructor(JNIEnvironment jni, Breakpoint bp) {
JNIObjectHandle serializeTargetClass = getObjectArgument(1);
String serializeTargetClassName = getClassNameOrNull(jni, serializeTargetClass);
long checksum = 0;
String checksum = "0";
List<SerializationInfo> traceCandidates = new ArrayList<>();
CheckSumCalculator checkSumCalculator = new CheckSumCalculator(jni, bp);
JNIObjectHandle objectStreamClassInstance = newObjectL(jni, bp.clazz, bp.method, serializeTargetClass);
Expand All @@ -878,11 +879,15 @@ private static boolean objectStreamClassConstructor(JNIEnvironment jni, Breakpoi
return true;
}
if (result.equals(true)) {
checksum = checkSumCalculator.calculateChecksum(getConsClassName(jni, bp.clazz, objectStreamClassInstance), serializeTargetClassName, serializeTargetClass);
try {
checksum = checkSumCalculator.calculateChecksum(getConsClassName(jni, bp.clazz, objectStreamClassInstance), serializeTargetClassName, serializeTargetClass);
} catch (NoSuchAlgorithmException e) {
throw VMError.shouldNotReachHere("Building serialization checksum failed", e);
}
}
traceCandidates.add(new SerializationInfo(serializeTargetClassName, checksum));

/**
/*
* When the ObjectStreamClass instance is created for the given serializeTargetClass, some
* additional ObjectStreamClass instances (usually the super classes) are created
* recursively. Call ObjectStreamClass.getClassDataLayout0() can get all of them.
Expand All @@ -905,9 +910,14 @@ private static boolean objectStreamClassConstructor(JNIEnvironment jni, Breakpoi
if (!jniFunctions().getIsSameObject().invoke(jni, oscInstanceInSlot, objectStreamClassInstance)) {
JNIObjectHandle oscClazz = callObjectMethod(jni, oscInstanceInSlot, javaIoObjectStreamClassForClassMId);
String oscClassName = getClassNameOrNull(jni, oscClazz);
traceCandidates.add(new SerializationInfo(oscClassName,
checkSumCalculator.calculateChecksum(getConsClassName(jni,
bp.clazz, oscInstanceInSlot), oscClassName, oscClazz)));
String calculatedChecksum;
try {
calculatedChecksum = checkSumCalculator.calculateChecksum(getConsClassName(jni,
bp.clazz, oscInstanceInSlot), oscClassName, oscClazz);
} catch (NoSuchAlgorithmException e) {
throw VMError.shouldNotReachHere("Building serialization checksum failed", e);
}
traceCandidates.add(new SerializationInfo(oscClassName, calculatedChecksum));
}
}
}
Expand Down Expand Up @@ -1402,10 +1412,10 @@ public int hashCode() {
}

private static final class SerializationInfo {
private String className;
private long checksum;
private final String className;
private final String checksum;

SerializationInfo(String serializeTargetClassName, long checksum) {
SerializationInfo(String serializeTargetClassName, String checksum) {
this.className = serializeTargetClassName;
this.checksum = checksum;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,37 +39,40 @@

public class SerializationConfiguration implements JsonPrintable {

private final ConcurrentHashMap<String, Set<Long>> serializations = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Set<String>> serializations = new ConcurrentHashMap<>();

public void addAll(String serializationTargetClass, Collection<Long> checksums) {
public void addAll(String serializationTargetClass, Collection<String> checksums) {
serializations.computeIfAbsent(serializationTargetClass, key -> new LinkedHashSet<>()).addAll(checksums);
}

public void add(String serializationTargetClass, Long checksum) {
public void add(String serializationTargetClass, String checksum) {
addAll(serializationTargetClass, Collections.singleton(checksum));
}

public boolean contains(String serializationTargetClass, Long checksum) {
return serializations.contains(serializationTargetClass) && serializations.get(serializationTargetClass).contains(checksum);
public boolean contains(String serializationTargetClass, String checksum) {
Set<String> checksums = serializations.get(serializationTargetClass);
return checksums != null && checksums.contains(checksum);
}

@Override
public void printJson(JsonWriter writer) throws IOException {
writer.append('[').indent();
String prefix = "";
for (Map.Entry<String, Set<Long>> entry : serializations.entrySet()) {
for (Map.Entry<String, Set<String>> entry : serializations.entrySet()) {
writer.append(prefix);
writer.newline().append('{').newline();
String className = entry.getKey();
writer.quote("name").append(":").quote(className);
Set<Long> checksums = entry.getValue();
Set<String> checksums = entry.getValue();
if (!checksums.isEmpty()) {
writer.append(",").newline();
writer.quote("checksum").append(':');
if (checksums.size() == 1) {
writer.append(checksums.iterator().next().toString());
writer.quote(checksums.iterator().next());
} else {
writer.append(checksums.stream().map(String::valueOf).collect(Collectors.joining(", ", "[", "]")));
writer.append(checksums.stream()
.map(JsonWriter::quoteString)
.collect(Collectors.joining(", ", "[", "]")));
}
writer.newline();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,13 @@ public JsonWriter quote(Object o) throws IOException {
}

public JsonWriter quote(String s) throws IOException {
writer.write(quoteString(s));
return this;
}

public static String quoteString(String s) {
if (s == null) {
return append("null");
return "null";
}
StringBuilder sb = new StringBuilder(2 + s.length() + 8 /* room for escaping */);
sb.append('"');
Expand All @@ -85,8 +90,7 @@ public JsonWriter quote(String s) throws IOException {
}
}
sb.append('"');
writer.write(sb.toString());
return this;
return sb.toString();
}

public JsonWriter newline() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
*/
package com.oracle.svm.configure.trace;

import com.oracle.svm.configure.config.SerializationConfiguration;

import java.util.List;
import java.util.Map;

import com.oracle.svm.configure.config.SerializationConfiguration;

public class SerializationProcessor extends AbstractProcessor {
private final SerializationConfiguration serializationConfiguration;

Expand All @@ -51,7 +51,7 @@ void processEntry(Map<String, ?> entry) {
List<?> args = (List<?>) entry.get("args");
if ("ObjectStreamClass.<init>".equals(function)) {
expectSize(args, 2);
serializationConfiguration.add((String) args.get(0), (Long) args.get(1));
serializationConfiguration.add((String) args.get(0), (String) args.get(1));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ public void parseAndRegister(Reader reader) throws IOException {
Map<String, Object> data = asMap(serializationKey, "second level of document must be serialization descriptor objects ");
String targetSerializationClass = asString(data.get("name"));
Object checksumValue = data.get("checksum");
List<Long> checksums = new ArrayList<>();
List<String> checksums = new ArrayList<>();
if (checksumValue != null) {
List<Object> jsonChecksums;
try {
jsonChecksums = asList(checksumValue, "list of checksums");
} catch (JSONParserException e) {
jsonChecksums = Collections.singletonList(asLong(checksumValue, "checksum"));
jsonChecksums = Collections.singletonList(asString(checksumValue, "checksum"));
}
for (Object jsonChecksum : jsonChecksums) {
checksums.add(asLong(jsonChecksum, "checksum"));
checksums.add(asString(jsonChecksum, "checksum"));
}
}
consumer.accept(targetSerializationClass, checksums);
Expand All @@ -68,6 +68,6 @@ public void parseAndRegister(Reader reader) throws IOException {

@FunctionalInterface
public interface SerializationParserFunction {
void accept(String targetSerializationClass, List<Long> checksum);
void accept(String targetSerializationClass, List<String> checksum);
}
}
Loading

0 comments on commit 72439a3

Please sign in to comment.