spring-messaging: initial integration & improve project structure (#8573)

This commit is contained in:
Patrice.S 2022-09-23 19:34:35 +02:00 committed by GitHub
parent 4a8e538e4b
commit 551ad63712
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 198 additions and 44 deletions

View File

@ -18,19 +18,26 @@ FROM gcr.io/oss-fuzz-base/base-builder-jvm
RUN apt update && apt install -y openjdk-17-jdk
RUN git clone --depth 1 https://github.com/google/fuzzing && \
mv fuzzing/dictionaries/xml.dict $SRC/GenericXmlApplicationContextFuzzer.dict && \
rm -rf fuzzing
RUN git clone --depth 1 https://github.com/dvyukov/go-fuzz-corpus && \
zip -j $SRC/GenericXmlApplicationContextFuzzer_seed_corpus.zip go-fuzz-corpus/xml/corpus/* && \
rm -rf go-fuzz-corpus
RUN git clone https://github.com/spring-projects/spring-framework
COPY add-shadow-*.diff $SRC/
RUN cd spring-framework && (for i in ${SRC}/add-shadow-*.diff; do tr -d '\015' < $i | git apply; done )
COPY build.sh $SRC/
COPY *.dict *.java *.xml $SRC/
COPY jdbc $SRC/jdbc/
COPY spring-aop $SRC/spring-aop/
COPY spring-beans $SRC/spring-beans/
COPY spring-context $SRC/spring-context/
COPY spring-expression $SRC/spring-expression/
COPY spring-jdbc $SRC/spring-jdbc/
COPY spring-tx $SRC/spring-tx/
COPY spring-web $SRC/spring-web/
COPY spring-messaging $SRC/spring-messaging/
RUN git clone --depth 1 https://github.com/google/fuzzing && \
mv fuzzing/dictionaries/xml.dict $SRC/spring-context/XmlApplicationContextFuzzer.dict && \
rm -rf fuzzing
RUN git clone --depth 1 https://github.com/dvyukov/go-fuzz-corpus && \
zip -j $SRC/spring-context/XmlApplicationContextFuzzer_seed_corpus.zip go-fuzz-corpus/xml/corpus/* && \
rm -rf go-fuzz-corpus
WORKDIR $SRC/spring-framework

View File

@ -0,0 +1,11 @@
diff --git a/spring-messaging/spring-messaging.gradle b/spring-messaging/spring-messaging.gradle
index cb54d42e59..e48a0d00a7 100644
--- a/spring-messaging/spring-messaging.gradle
+++ b/spring-messaging/spring-messaging.gradle
@@ -1,5 +1,6 @@
description = "Spring Messaging"
+apply plugin: "com.github.johnrengelman.shadow"
apply plugin: "kotlin"
apply plugin: "kotlinx-serialization"

View File

@ -15,7 +15,7 @@
#
################################################################################
cp $SRC/{*.zip,*.dict} $OUT
find $SRC/spring* -name *.dict -o -name *zip -exec cp {} $OUT/ \;
export JAVA_HOME="$OUT/open-jdk-17"
mkdir -p $JAVA_HOME
@ -25,20 +25,21 @@ CURRENT_VERSION=$(./gradlew properties --console=plain | sed -nr "s/^version:\ (
ALL_JARS="";
function installShadowJar {
function install_shadowJar {
./gradlew shadowJar --build-file spring-$1/spring-$1.gradle -x javadoc -x test
install -v "spring-$1/build/libs/spring-$1-${CURRENT_VERSION}-all.jar" "$OUT/spring-$1.jar";
ALL_JARS="${ALL_JARS} spring-$1.jar";
}
installShadowJar context;
installShadowJar core;
installShadowJar jdbc;
installShadowJar orm;
installShadowJar web;
installShadowJar webmvc;
installShadowJar test;
installShadowJar tx;
install_shadowJar context;
install_shadowJar core;
install_shadowJar jdbc;
install_shadowJar orm;
install_shadowJar web;
install_shadowJar webmvc;
install_shadowJar test;
install_shadowJar tx;
install_shadowJar messaging;
# The classpath at build-time includes the project jars in $OUT as well as the
# Jazzer API.
@ -47,30 +48,39 @@ BUILD_CLASSPATH=$(echo $ALL_JARS | xargs printf -- "$OUT/%s:"):$JAZZER_API_PATH:
# All .jar and .class files lie in the same directory as the fuzzer at runtime.
RUNTIME_CLASSPATH=$(echo $ALL_JARS | xargs printf -- "\$this_dir/%s:"):\$this_dir
javac -cp $BUILD_CLASSPATH $SRC/*.java --release 17
install -v $SRC/*.class $OUT
function create_fuzz_targets() {
mkdir -p $SRC/$1
mkdir -p $OUT/$1
javac -cp $BUILD_CLASSPATH $SRC/$1/*.java --release 17
javac -cp $BUILD_CLASSPATH $SRC/jdbc/*.java --release 17
install -vd $OUT/jdbc
install -v $SRC/jdbc/*.class $OUT/jdbc
install -v $SRC/JdbcCoreMapperFuzzerBeans.xml $OUT
for fuzzer in $SRC/$1/*Fuzzer.java; do
fuzzer_basename=$(basename -s .java $fuzzer)
for fuzzer in $SRC/*Fuzzer.java; do
fuzzer_basename=$(basename -s .java $fuzzer)
javac -cp $BUILD_CLASSPATH $fuzzer --release 17
cp $SRC/$fuzzer_basename*.class $OUT/
# Create an execution wrapper that executes Jazzer with the correct arguments.
echo "#!/bin/sh
# LLVMFuzzerTestOneInput for fuzzer detection.
this_dir=\$(dirname \"\$0\")
JAVA_HOME=\"\$this_dir/open-jdk-17/\" \
LD_LIBRARY_PATH=\"\$this_dir/open-jdk-17/lib/server\":\$this_dir \
\$this_dir/jazzer_driver --agent_path=\$this_dir/jazzer_agent_deploy.jar \
--cp=$RUNTIME_CLASSPATH \
--target_class=$fuzzer_basename \
--instrumentation_excludes=org.aspectj.weaver.** \
--jvm_args=\"-Xmx2048m\" \
\$@" > $OUT/$fuzzer_basename
chmod u+x $OUT/$fuzzer_basename
done
# Create an execution wrapper that executes Jazzer with the correct arguments.
echo "#!/bin/sh
# LLVMFuzzerTestOneInput for fuzzer detection.
this_dir=\$(dirname \"\$0\")
JAVA_HOME=\"\$this_dir/open-jdk-17/\" \
LD_LIBRARY_PATH=\"\$this_dir/open-jdk-17/lib/server\":\$this_dir \
\$this_dir/jazzer_driver --agent_path=\$this_dir/jazzer_agent_deploy.jar \
--cp=$RUNTIME_CLASSPATH \
--target_class=$fuzzer_basename \
--instrumentation_excludes=org.aspectj.weaver.** \
--jvm_args=\"-Xmx2048m\" \
\$@" > $OUT/$fuzzer_basename
chmod u+x $OUT/$fuzzer_basename
done
cp $SRC/$1/*.class $OUT/
}
create_fuzz_targets spring-aop
create_fuzz_targets spring-beans
create_fuzz_targets spring-context
create_fuzz_targets spring-expression
create_fuzz_targets spring-tx
create_fuzz_targets spring-web
create_fuzz_targets spring-jdbc
create_fuzz_targets spring-messaging
cp $SRC/spring-jdbc/*.xml $OUT/spring-jdbc/

View File

@ -1,3 +1,18 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;

View File

@ -0,0 +1,111 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow;
import org.springframework.core.annotation.SynthesizingMethodParameter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.converter.MarshallingMessageConverter;
import org.springframework.messaging.converter.StringMessageConverter;
import org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException;
import org.springframework.messaging.handler.annotation.support.PayloadMethodArgumentResolver;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.util.MimeType;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class PayloadMethodArgumentResolverFuzzer {
public static Class<?>[] classes = { DummyClass.class, Integer.class, String.class, Byte.class, List.class, Map.class,
TreeMap.class, BitSet.class, TimeZone.class, Date.class, Calendar.class, Locale.class };
public static void fuzzerTestOneInput(FuzzedDataProvider data) {
String payload = data.consumeString(200);
String headerName = data.consumeString(50);
String headerValue = data.consumeString(50);
Validator validator = new Validator() {
@Override
public boolean supports(Class<?> clazz) {
return true;
}
@Override
public void validate(Object target, Errors errors) {}
};
PayloadMethodArgumentResolver resolver = new PayloadMethodArgumentResolver(new StringMessageConverter(), validator);
Method method;
SynthesizingMethodParameter parameter;
Message<String> message;
try {
method = (data.pickValue(classes)).getDeclaredMethod("foo", data.consumeBoolean() ? data.pickValue(classes) : null);
parameter = new SynthesizingMethodParameter(method, data.consumeInt(0, 100));
message = MessageBuilder.withPayload(payload)
.setHeader(headerName, headerValue)
.build();
message.getHeaders().get(headerName, data.pickValue(classes));
} catch (NoSuchMethodException | IllegalArgumentException ignored) {
return;
}
try {
Object result = resolver.resolveArgument(parameter, message);
if (!Objects.equals(result, payload)) {
throw new FuzzerSecurityIssueLow("Payload is different");
}
} catch (MethodArgumentNotValidException ignored) {
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static class DummyClass {
public TreeMap<String, Integer> _treeMap;
public List<String> _arrayList;
public Set<String> _hashSet;
public Map<String, Object> _hashMap;
public List<Integer> _asList = Arrays.asList(1, 2, 3);
public int[] _intArray;
public long[] _longArray;
public short[] _shortArray;
public float[] _floatArray;
public double[] _doubleArray;
public byte[] _byteArray;
public char[] _charArray;
public String[] _stringArray;
public BitSet _bitSet;
public Date _date;
public TimeZone _timeZone;
public Calendar _calendar;
public Locale _locale;
public Integer[] _integerArray;
public boolean _boolean;
public char _char;
public byte _byte;
public short _short;
public int _int;
public float _float;
public void foo(String dummy) {}
}
}