diff --git a/FuzzTesting/oss-fuzz-integration/Dockerfile b/FuzzTesting/oss-fuzz-integration/Dockerfile new file mode 100644 index 00000000..c5555ca1 --- /dev/null +++ b/FuzzTesting/oss-fuzz-integration/Dockerfile @@ -0,0 +1,15 @@ +# OSS-Fuzz build image for MacPaw/OpenAI. +# +# Apply (alongside build.sh and project.yaml) at +# `projects/macpaw-openai/Dockerfile` in a fork of +# https://github.com/google/oss-fuzz. + +FROM gcr.io/oss-fuzz-base/base-builder-swift + +# Clone the SDK under $SRC so build.sh can `cd` into it. OSS-Fuzz pins +# the commit per-run from project.yaml; here we just default to main. +RUN git clone --depth=1 https://github.com/MacPaw/OpenAI.git $SRC/OpenAI + +WORKDIR $SRC/OpenAI + +COPY build.sh $SRC/ diff --git a/FuzzTesting/oss-fuzz-integration/README.md b/FuzzTesting/oss-fuzz-integration/README.md new file mode 100644 index 00000000..57094ade --- /dev/null +++ b/FuzzTesting/oss-fuzz-integration/README.md @@ -0,0 +1,68 @@ +# OSS-Fuzz integration templates + +The actual OSS-Fuzz project descriptor for MacPaw/OpenAI lives upstream +at [`google/oss-fuzz/projects/macpaw-openai/`](https://github.com/google/oss-fuzz/tree/master/projects). +The three files here (`project.yaml`, `Dockerfile`, `build.sh`) are the +templates a maintainer applies to their fork of `google/oss-fuzz` when +they want to register the project. + +This directory is intentionally checked in so the integration source of +truth lives next to the harnesses they describe. Update these files +whenever you add or rename a harness in `FuzzTesting/Package.swift`. + +## How to submit upstream + +1. **Confirm Swift support is acceptable for the project.** OSS-Fuzz + Swift support uses `gcr.io/oss-fuzz-base/base-builder-swift`. It + works but is not as mature as the C/C++/Rust/Go/Python paths — read + + before committing. + +2. **Decide on contacts.** Edit `project.yaml`: + - `primary_contact` must be an email tied to a Google account + (so OSS-Fuzz can grant access to the private bug-report + dashboard). + - `auto_ccs` is optional and accepts multiple addresses. + +3. **Fork `google/oss-fuzz`.** + ```sh + gh repo fork google/oss-fuzz --clone + cd oss-fuzz + ``` + +4. **Copy these templates into the fork.** + ```sh + mkdir -p projects/macpaw-openai + cp /path/to/OpenAI/FuzzTesting/oss-fuzz-integration/project.yaml \ + /path/to/OpenAI/FuzzTesting/oss-fuzz-integration/Dockerfile \ + /path/to/OpenAI/FuzzTesting/oss-fuzz-integration/build.sh \ + projects/macpaw-openai/ + chmod +x projects/macpaw-openai/build.sh + ``` + Then fill in the `TODO(maintainer)` contact lines in + `projects/macpaw-openai/project.yaml`. + +5. **Smoke-test the integration locally.** OSS-Fuzz ships a helper + driver: + ```sh + python infra/helper.py build_image macpaw-openai + python infra/helper.py build_fuzzers --sanitizer address macpaw-openai + python infra/helper.py check_build macpaw-openai + python infra/helper.py run_fuzzer macpaw-openai FuzzResponseStreamEventDecoder + ``` + +6. **Open the PR upstream.** + ```sh + git checkout -b macpaw-openai + git add projects/macpaw-openai + git commit -m "Add MacPaw/OpenAI project" + git push -u origin macpaw-openai + gh pr create --repo google/oss-fuzz --base master + ``` + +## Keeping these templates in sync + +When `FuzzTesting/Package.swift` gains or renames a harness, update the +`HARNESSES=(...)` array in `build.sh`. Once your upstream project is +live, mirror the change into `projects/macpaw-openai/build.sh` in the +`google/oss-fuzz` repo (a small follow-up PR). diff --git a/FuzzTesting/oss-fuzz-integration/build.sh b/FuzzTesting/oss-fuzz-integration/build.sh new file mode 100755 index 00000000..c2b6c84e --- /dev/null +++ b/FuzzTesting/oss-fuzz-integration/build.sh @@ -0,0 +1,45 @@ +#!/bin/bash -eu +# +# OSS-Fuzz build script for MacPaw/OpenAI. +# +# Apply at `projects/macpaw-openai/build.sh` in a fork of +# https://github.com/google/oss-fuzz. +# +# Builds each libFuzzer harness declared in `FuzzTesting/Package.swift` +# and copies the binary plus a zipped seed corpus into $OUT. +# +# Invoked by OSS-Fuzz with the standard environment: +# $SRC project source root +# $OUT output directory the platform expects binaries in +# $CFLAGS / $CXXFLAGS sanitizer flags +# $LIB_FUZZING_ENGINE static archive providing libFuzzer main + +cd "$SRC/OpenAI/FuzzTesting" + +HARNESSES=( + FuzzResponseStreamEventDecoder + FuzzChatResultDecoder + FuzzChatStreamResultDecoder + FuzzResponseObjectDecoder + FuzzAudioTranscriptionStreamResultDecoder +) + +# `-DFUZZING_ENABLED` removes the in-source `@main` replay entry point +# so libFuzzer's own main (provided via -sanitize=fuzzer) drives +# `LLVMFuzzerTestOneInput`. +SWIFT_FLAGS=( + -Xswiftc -sanitize=fuzzer,address + -Xswiftc -parse-as-library + -Xswiftc -DFUZZING_ENABLED +) + +swift build -c debug "${SWIFT_FLAGS[@]}" + +for harness in "${HARNESSES[@]}"; do + cp ".build/debug/${harness}" "$OUT/${harness}" + + corpus_dir="FuzzCorpus/${harness}" + if [ -d "$corpus_dir" ]; then + (cd "$corpus_dir" && zip -q -r "$OUT/${harness}_seed_corpus.zip" .) + fi +done diff --git a/FuzzTesting/oss-fuzz-integration/project.yaml b/FuzzTesting/oss-fuzz-integration/project.yaml new file mode 100644 index 00000000..262c1621 --- /dev/null +++ b/FuzzTesting/oss-fuzz-integration/project.yaml @@ -0,0 +1,29 @@ +# OSS-Fuzz project descriptor. Apply this file (after filling in the +# TODO contact fields) at `projects/macpaw-openai/project.yaml` in a +# fork of https://github.com/google/oss-fuzz. + +homepage: "https://github.com/MacPaw/OpenAI" +language: swift +main_repo: "https://github.com/MacPaw/OpenAI.git" + +# TODO(maintainer): replace with the maintainer's email. Must be the +# address tied to a Google account so OSS-Fuzz can grant access to the +# private bug reports dashboard. +primary_contact: "TODO@example.com" + +# TODO(maintainer): optional additional addresses to CC on findings. +auto_ccs: + - "TODO@example.com" + +# Build the harnesses with both AddressSanitizer and +# UndefinedBehaviorSanitizer. Memory-sanitizer is omitted because +# libFuzzer's MSan support for Swift is not reliable. +sanitizers: + - address + - undefined + +architectures: + - x86_64 + +fuzzing_engines: + - libfuzzer