Skip to content
Merged
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
21 changes: 21 additions & 0 deletions .clusterfuzzlite/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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-rust
COPY . $SRC/datafusion-sqlparser-rs
WORKDIR $SRC/datafusion-sqlparser-rs
COPY ./.clusterfuzzlite/build.sh $SRC/
34 changes: 34 additions & 0 deletions .clusterfuzzlite/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.

set -eu

cd "$SRC/datafusion-sqlparser-rs"
# the base image's RUSTUP_TOOLCHAIN (nightly) overrides the rust-toolchain pin, so we name none
cargo fuzz build -O --fuzz-dir fuzz

targets=$(cargo fuzz list --fuzz-dir fuzz)
if [ -z "$targets" ]; then
echo "cargo fuzz list named no target" >&2
exit 1
fi

target_dir=fuzz/target/x86_64-unknown-linux-gnu/release
for name in $targets; do
cp "$target_dir/$name" "$OUT/"
done
20 changes: 20 additions & 0 deletions .clusterfuzzlite/project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.

language: rust
sanitizers:
- address
49 changes: 49 additions & 0 deletions .github/workflows/cflite_batch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.

name: ClusterFuzzLite batch fuzzing
on:
schedule:
- cron: '0 06 * * *' # 06:00 UTC daily
permissions: read-all
jobs:
BatchFuzzing:
runs-on: ubuntu-latest
permissions:
contents: write
strategy:
fail-fast: false
matrix:
sanitizer:
- address
steps:
- name: Build Fuzzers (${{ matrix.sanitizer }})
id: build
uses: google/clusterfuzzlite/actions/build_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1
with:
language: rust
sanitizer: ${{ matrix.sanitizer }}
- name: Run Fuzzers (${{ matrix.sanitizer }})
id: run
uses: google/clusterfuzzlite/actions/run_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
fuzz-seconds: 3600
mode: 'batch'
sanitizer: ${{ matrix.sanitizer }}
storage-repo: ${{ github.server_url }}/${{ github.repository }}.git
storage-repo-branch: clusterfuzzlite
42 changes: 42 additions & 0 deletions .github/workflows/cflite_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.

name: ClusterFuzzLite continuous builds

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about the value of running fuzzing on main pushes as well -- my rationale is that if the fuzz test hits an issue on main then there will be a red x recorded on that commit and we will perhaps be mislead into thinking that a bug was introduced by that commit (or at least will have to rule it out)

Also it seems strange to me to make the amount of effort devoted to fuzz testing a function of the number of PRs merged to main (which is what this will do)

I personally suggest just running the fuzz testing in batch mode to begin with. If you want more fuzz time, then just crank it up there

@LucaCappelletti94 LucaCappelletti94 Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This particular workflow is solely focused on ensuring the fuzzer harnesses keep building. It does not run the harnesses themselves.

It additionally works alongside the PR fuzzing job as it is the harness built that is used for the differential fuzzing.

on:
push:
branches:
- main
permissions: read-all
jobs:
Build:
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ github.ref }}
cancel-in-progress: true
strategy:
fail-fast: false
matrix:
sanitizer:
- address
steps:
- name: Build Fuzzers (${{ matrix.sanitizer }})
id: build
uses: google/clusterfuzzlite/actions/build_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1
with:
language: rust
sanitizer: ${{ matrix.sanitizer }}
upload-build: true
48 changes: 48 additions & 0 deletions .github/workflows/cflite_pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.

name: ClusterFuzzLite PR fuzzing

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

likewise here I think PR fuzzing will just generate more confusion to contributors than it is worth -- if the fuzz test fails on their PR they probably will either

  1. Rerun it
  2. Get confused and think it is related to something in their PR

I think both of these are confusing outcomes and recommend against it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My hope was that, as the fuzzer stabilizes over time, the bugs that get raised by a PR fuzzing run are exactly bugs of the PR, and this should simplify a lot the job of reviewers.

I do agree that at this time most bugs raised by the fuzzer are pre-existing things that need handling before it can be deployed on PRs as at this time yes they would be confusing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a tad new to ClusterFuzzLite specifically, so I double checked. In theory, IF I configured this correctly (and I primarely copied the documentation examples) if a bug exists on main and survives in the PR, it is reported as pre-existing, and if it exists in the PR and not in the main it is noted as new bug. Only the latter case should be marked as a blocking error.

on:
pull_request:
permissions: read-all
jobs:
PR:
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ github.ref }}
cancel-in-progress: true
strategy:
fail-fast: false
matrix:
sanitizer:
- address
steps:
- name: Build Fuzzers (${{ matrix.sanitizer }})
id: build
uses: google/clusterfuzzlite/actions/build_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1
with:
language: rust
github-token: ${{ secrets.GITHUB_TOKEN }}
sanitizer: ${{ matrix.sanitizer }}
- name: Run Fuzzers (${{ matrix.sanitizer }})
id: run
uses: google/clusterfuzzlite/actions/run_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
fuzz-seconds: 600
mode: 'code-change'
sanitizer: ${{ matrix.sanitizer }}
42 changes: 42 additions & 0 deletions .github/workflows/cflite_prune.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.

name: ClusterFuzzLite corpus pruning

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not familiar with corpus pruning -- maybe a definition to the link would be helpful
Also I don't understand why this is a separate job from fuzz testing -- why not make the daily schedule a single action (perhaps with two jobs)?

@LucaCappelletti94 LucaCappelletti94 Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TLDR of it, the corpus entries over time become overlapping/redundant, and we want to keep the minimum set of entries that seed the maximum coverage. This minimization procedure trims down the corpus by assigning to each entry a fingerprint of the coverage it produces, and then keeps sufficiently distinct ones. It is generally done less frequently than fuzzing itself.

I will add a definition and link the documentation.

on:
schedule:
- cron: '0 05 * * *' # 05:00 UTC, an hour before batch fuzzing
permissions: read-all
jobs:
Pruning:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Build Fuzzers
id: build
uses: google/clusterfuzzlite/actions/build_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1
with:
language: rust
- name: Run Fuzzers
id: run
uses: google/clusterfuzzlite/actions/run_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
fuzz-seconds: 600
mode: 'prune'
storage-repo: ${{ github.server_url }}/${{ github.repository }}.git
storage-repo-branch: clusterfuzzlite
4 changes: 4 additions & 0 deletions docs/fuzzing.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ cd fuzz
cargo +nightly fuzz run fuzz_parse_sql -- -max_total_time=600
```

ClusterFuzzLite runs continuous fuzzing. Every pull request fuzzes for 10 minutes in
`code-change` mode, a daily batch job grows the shared corpus stored on the
`clusterfuzzlite` branch, and a daily prune compacts it.

Crashes land in `artifacts/<target>/` and replay with `cargo fuzz run <target> <crash-file>`.
Loading