Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 19 additions & 28 deletions projects/okhttp/Dockerfile
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
# 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.
#
################################################################################

FROM gcr.io/oss-fuzz-base/base-builder-jvm

RUN curl -L https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.zip -o maven.zip && \
unzip maven.zip -d $SRC/maven-3.6.3 && \
rm -rf maven.zip
# Install Gradle (wrapper usable too, but install for convenience)
RUN apt-get update && apt-get install -y curl unzip && rm -rf /var/lib/apt/lists/*

ARG GRADLE_VERSION=8.13
RUN curl -fsSL "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" -o /tmp/gradle.zip \
&& unzip -q /tmp/gradle.zip -d /opt/gradle \
&& rm /tmp/gradle.zip
ENV PATH="/opt/gradle/gradle-${GRADLE_VERSION}/bin:${PATH}"

# Copy OkHttp source and fuzz module into image at /src/okhttp
# In OSS-Fuzz production, the infra clones the main repo based on project.yaml.
# For local testing you can COPY your fork or let build.sh fetch it.
WORKDIR /src/okhttp

ENV MVN $SRC/maven-3.6.3/apache-maven-3.6.3/bin/mvn
# Copy build scripts and fuzzers (adjust if you vendor fuzz module in the repo)
COPY build.sh /src/build.sh
COPY build.sh /src/okhttp/build.sh
COPY fuzz /opt/okhttp-fuzz

WORKDIR ${SRC}
#
# clone repository
#
RUN git clone https://github.com/square/okhttp.git
ENV MAVEN_OPTS=-Xmx2g

ADD pom.xml build.sh ${SRC}/
ADD src/ ${SRC}/src/
WORKDIR ${SRC}/okhttp
RUN chmod +x /src/build.sh /src/okhttp/build.sh
14 changes: 14 additions & 0 deletions projects/okhttp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Purpose
- Scaffold an OSS-Fuzz project for OkHttp (Java/Kotlin) using Jazzer.
- Use this as a starting point for your oss-fuzz fork under projects/okhttp.

Files
- Dockerfile: base on base-builder-java; installs Gradle and builds fuzz targets.
- build.sh: assembles classpath and copies jazzer targets to $OUT.
- fuzz/UrlFuzzer.java: example Jazzer fuzzer over OkHttp HttpUrl parsing.

How to use
1) Fork https://github.com/google/oss-fuzz and create projects/okhttp/ with these files.
2) Ensure your OkHttp repo has the fuzz module (fuzz/) or copy it inside the Docker image.
3) Locally validate with OSS-Fuzz helper or trigger via Buttercup using fuzz_tooling_url/ref.

152 changes: 73 additions & 79 deletions projects/okhttp/build.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,92 +1,86 @@
#!/bin/bash -eu
# 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.
#
################################################################################
# Build OkHttp and Jazzer fuzz targets; copy artifacts to $OUT

GRADLE_FLAGS="-x javadoc -x test -Dfile.encoding=UTF-8"
MVN_FLAGS="-DskipTests -Drat.ignoreErrors=true"
ALL_JARS=""
export JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"
export PATH="$JAVA_HOME/bin:$PATH"

# install the build servers' jazzer-api into the maven repository
pushd "/tmp"
${MVN} install:install-file -Dfile=${JAZZER_API_PATH} \
-DgroupId="com.code-intelligence" \
-DartifactId="jazzer-api" \
-Dversion="0.12.0" \
-Dpackaging=jar
popd
OKHTTP_SRC_DIR="/src/okhttp"
FUZZ_SRC_DIR="$OKHTTP_SRC_DIR/fuzz"
FUZZ_BUILD_DIR="$FUZZ_SRC_DIR/build"
JAZZER_API="/usr/local/share/jazzer/api"
DEFAULT_FUZZ_SRC="/opt/okhttp-fuzz"

pushd "${SRC}/okhttp/okhttp"
../gradlew jar
../gradlew publishToMavenLocal ${GRADLE_FLAGS}
CURRENT_VERSION=$(../gradlew properties --console=plain | sed -nr "s/^version:\ (.*)/\1/p")
popd

pushd "${SRC}/okhttp/okhttp-logging-interceptor"
../gradlew jar
../gradlew publishToMavenLocal ${GRADLE_FLAGS}
CURRENT_VERSION=$(../gradlew properties --console=plain | sed -nr "s/^version:\ (.*)/\1/p")
popd

pushd "${SRC}/okhttp/mockwebserver"
../gradlew jar
../gradlew publishToMavenLocal ${GRADLE_FLAGS}
CURRENT_VERSION=$(../gradlew properties --console=plain | sed -nr "s/^version:\ (.*)/\1/p")
popd

pushd ${SRC}
${MVN} package -DokhttpVersion="${CURRENT_VERSION}" ${MVN_FLAGS}
install -v target/okhttp-fuzzer-${CURRENT_VERSION}.jar ${OUT}/okhttp-fuzzer-${CURRENT_VERSION}.jar
ALL_JARS="${ALL_JARS} okhttp-fuzzer-${CURRENT_VERSION}.jar"
popd
# If the source is not already present under /src/okhttp, you can clone here.
# Example (uncomment and adjust):
# git clone --depth 1 https://github.com/square/okhttp.git "$OKHTTP_SRC_DIR"

# Build OkHttp with Gradle (prefer system gradle to avoid wrapper downloads)
GRADLE_CMD=""
if command -v gradle >/dev/null 2>&1; then
GRADLE_CMD="$(command -v gradle)"
elif [ -f "$OKHTTP_SRC_DIR/gradlew" ]; then
GRADLE_CMD="$OKHTTP_SRC_DIR/gradlew"
fi

if [ -n "$GRADLE_CMD" ]; then
pushd "$OKHTTP_SRC_DIR" >/dev/null
# Try the MPP JVM jar task first; fall back to assemble
if "$GRADLE_CMD" --no-daemon :okhttp:jvmJar -x test -x javadoc; then
echo "Built :okhttp:jvmJar"
else
echo ":okhttp:jvmJar not available, trying :okhttp:assemble"
"$GRADLE_CMD" --no-daemon :okhttp:assemble -x test -x javadoc
fi
popd >/dev/null
else
echo "Gradle not found; please ensure gradle is installed in the image." >&2
exit 1
fi

# The classpath at build-time includes the project jars in $OUT as well as the
# Jazzer API.
BUILD_CLASSPATH=$(echo $ALL_JARS | xargs printf -- "$OUT/%s:"):$JAZZER_API_PATH
# Ensure fuzz harness exists (copy from image if not present in source)
if [ ! -f "$FUZZ_SRC_DIR/UrlFuzzer.java" ] && [ -d "$DEFAULT_FUZZ_SRC" ]; then
mkdir -p "$FUZZ_SRC_DIR"
cp -r "$DEFAULT_FUZZ_SRC"/. "$FUZZ_SRC_DIR/"
fi

# 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
# Prepare jazzer target(s)
mkdir -p "$OUT" "$FUZZ_BUILD_DIR"
# Ensure downstream tests always have at least one artifact in /out.
touch "$OUT/.placeholder"

MVN_FUZZERS_PREFIX="src/main/java"
# Locate OkHttp jars produced by the build (MPP jvmJar or standard jar)
OKHTTP_JARS=$(find "$OKHTTP_SRC_DIR/okhttp/build/libs" -maxdepth 1 -type f -name "*.jar" 2>/dev/null || true)

for fuzzer in $(find ${SRC} -name '*Fuzzer.java'); do
stripped_path=$(echo ${fuzzer} | sed 's|^.*src/main/java/\(.*\).java$|\1|');
# the .java was stripped by sed
if (echo ${stripped_path} | grep ".java$"); then
continue;
fi
# Compile sample fuzzer (uses Jazzer JUnit FuzzTest)
CLASSPATH="$JAZZER_API/*"
if [ -n "$OKHTTP_JARS" ]; then
CLASSPATH="$OKHTTP_SRC_DIR/okhttp/build/libs/*:$CLASSPATH"
fi

fuzzer_basename=$(basename -s .java $fuzzer)
fuzzer_classname=$(echo ${stripped_path} | sed 's|/|.|g');
javac -encoding UTF-8 -cp "$CLASSPATH" "$FUZZ_SRC_DIR/UrlFuzzer.java" -d "$FUZZ_BUILD_DIR"

# Create an execution wrapper that executes Jazzer with the correct arguments.
echo "#!/bin/bash
# LLVMFuzzerTestOneInput for fuzzer detection.
this_dir=\$(dirname \"\$0\")
if [[ \"\$@\" =~ (^| )-runs=[0-9]+($| ) ]]; then
mem_settings='-Xmx1900m:-Xss900k'
else
mem_settings='-Xmx2048m:-Xss1024k'
# Package runtime: copy needed jars and fuzzer classes into $OUT
cp -f $OKHTTP_SRC_DIR/okhttp/build/libs/*.jar "$OUT" 2>/dev/null || true
cp -f /usr/local/share/jazzer/*.jar "$OUT" 2>/dev/null || true
# Copy jazzer drivers expected by OSS-Fuzz runner
if [ -d /usr/local/share/jazzer/bin ]; then
cp -f /usr/local/share/jazzer/bin/jazzer_driver "$OUT" 2>/dev/null || true
cp -f /usr/local/share/jazzer/bin/jazzer_driver_with_sanitizer "$OUT" 2>/dev/null || true
chmod +x "$OUT"/jazzer_driver* 2>/dev/null || true
fi
LD_LIBRARY_PATH=\"$JVM_LD_LIBRARY_PATH\":\$this_dir \
\$this_dir/jazzer_driver --agent_path=\$this_dir/jazzer_agent_deploy.jar \
--cp=${RUNTIME_CLASSPATH} \
--target_class=${fuzzer_classname} \
--jvm_args=\"\$mem_settings\" \
\$@" > $OUT/${fuzzer_basename}
chmod u+x $OUT/${fuzzer_basename}
done
mkdir -p "$OUT/fuzzer-classes"
cp -r "$FUZZ_BUILD_DIR"/* "$OUT/fuzzer-classes" 2>/dev/null || true

# Create execution wrapper for OSS-Fuzz
cat >"$OUT/UrlFuzzer" << 'EOF'
#!/bin/bash
set -euo pipefail
THIS_DIR=$(cd -- "$(dirname "$0")" && pwd)
JAZZER_JAR=$(ls "$THIS_DIR"/jazzer*.jar | head -n1)
CP="$THIS_DIR/*:$THIS_DIR/fuzzer-classes:$THIS_DIR"
exec java -cp "$CP" com.code_intelligence.jazzer.Jazzer \
--cp="$CP" \
--target_class=UrlFuzzer \
--instrumentation_includes='okhttp3.**'
EOF
chmod +x "$OUT/UrlFuzzer"
18 changes: 18 additions & 0 deletions projects/okhttp/fuzz/UrlFuzzer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import okhttp3.HttpUrl;

public class UrlFuzzer {
public static void fuzzerTestOneInput(FuzzedDataProvider data) {
String url = data.consumeString(2048);
try {
HttpUrl parsed = HttpUrl.parse(url);
if (parsed != null) {
parsed.host();
parsed.encodedPath();
parsed.querySize();
}
} catch (IllegalArgumentException ignored) {
// Expected for invalid inputs
}
}
}
20 changes: 9 additions & 11 deletions projects/okhttp/project.yaml
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
homepage: "https://square.github.io/okhttp/"
homepage: "https://github.com/JAY-Code-Create/okhttp"
language: jvm
main_repo: "https://github.com/square/okhttp.git"
main_repo: "https://github.com/JAY-Code-Create/okhttp.git"
sanitizers:
- none
fuzzing_engines:
- libfuzzer
sanitizers:
- address
architectures:
- x86_64
labels:
- jazzer
vendor_ccs:
- "[email protected]"
- "[email protected]"
- "[email protected]"
- "[email protected]"
- "[email protected]"
- "[email protected]"
- "[email protected]"
- trailofbits