Skip to content

Commit 2424252

Browse files
committed
Add fuzzing for qasm3 (#2167)
1 parent adbe623 commit 2424252

File tree

9 files changed

+66
-20
lines changed

9 files changed

+66
-20
lines changed

.github/workflows/fuzz.yml

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ env:
77
TMIN_LOG_FNAME: fuzz.tmin.log # File name to redirect the fuzzing input minimization log to.
88
GH_ISSUE_TEMPLATE_RFPATH: .github/ISSUE_TEMPLATE/fuzz_bug_report.md
99
# GitHub issue template rel file path.
10-
TARGET_NAME: compile # Fuzzing target name. Fuzzes the `compile` func of the Q# compiler.
1110
ARTIFACTS_RDPATH: fuzz/artifacts # Fuzzing artifacts rel dir path.
1211
SEEDS_RDPATH: fuzz/seed_inputs # Fuzzing seed inputs rel dir path.
1312
SEEDS_FNAME: list.txt # Fuzzing seed inputs list file name.
@@ -31,11 +30,15 @@ jobs:
3130
fuzz:
3231
name: Fuzzing
3332
strategy:
33+
fail-fast: false
3434
matrix:
3535
os: [ubuntu-latest] # Fuzzing is not supported on Win. The macos is temporarily removed
3636
# because of low availability.
37-
runs-on: ${{ matrix.os }}
37+
target_name: [qsharp, qasm3]
3838

39+
runs-on: ${{ matrix.os }}
40+
permissions:
41+
issues: write
3942
steps:
4043
- name: Install and Configure Tools
4144
run: |
@@ -49,29 +52,30 @@ jobs:
4952
submodules: "true"
5053

5154
- name: Gather the Seed Inputs
55+
if: matrix.target_name == 'qsharp'
5256
run: |
5357
cd $OWNER_RDPATH # Enter the dir containing the fuzzing infra.
5458
5559
# Clone the submodules of QDK:
5660
REPOS="Quantum Quantum-NC QuantumKatas QuantumLibraries iqsharp qdk-python qsharp-compiler qsharp-runtime"
5761
for REPO in $REPOS ; do
5862
git clone --depth 1 --single-branch --no-tags --recurse-submodules --shallow-submodules --jobs 4 \
59-
https://github.com/microsoft/$REPO.git $SEEDS_RDPATH/$TARGET_NAME/$REPO
63+
https://github.com/microsoft/$REPO.git $SEEDS_RDPATH/${{ matrix.target_name }}/$REPO
6064
done
6165
6266
# Build a comma-separated list of all the .qs files in $SEEDS_FNAME file:
63-
find $SEEDS_RDPATH/$TARGET_NAME -name "*.qs" | tr "\n" "," > \
64-
$SEEDS_RDPATH/$TARGET_NAME/$SEEDS_FNAME
67+
find $SEEDS_RDPATH/${{ matrix.target_name }} -name "*.qs" | tr "\n" "," > \
68+
$SEEDS_RDPATH/${{ matrix.target_name }}/$SEEDS_FNAME
6569
6670
- name: Build and Run the Fuzz Target
6771
run: |
6872
cd $OWNER_RDPATH # Enter the dir containing the fuzzing infra.
69-
cargo fuzz build --release --sanitizer=none --features do_fuzz $TARGET_NAME # Build the fuzz target.
73+
cargo fuzz build --release --sanitizer=none --features do_fuzz ${{ matrix.target_name }} # Build the fuzz target.
7074
7175
# Run fuzzing for specified number of seconds and redirect the `stderr` to a file
7276
# whose name is specified by the STDERR_LOG_FNAME env var:
73-
RUST_BACKTRACE=1 cargo fuzz run --release --sanitizer=none --features do_fuzz $TARGET_NAME -- \
74-
-seed_inputs=@$SEEDS_RDPATH/$TARGET_NAME/$SEEDS_FNAME \
77+
RUST_BACKTRACE=1 cargo fuzz run --release --sanitizer=none --features do_fuzz ${{ matrix.target_name }} -- \
78+
-seed_inputs=@$SEEDS_RDPATH/${{ matrix.target_name }}/$SEEDS_FNAME \
7579
-max_total_time=$DURATION_SEC \
7680
-rss_limit_mb=4096 \
7781
-max_len=20000 \
@@ -116,33 +120,33 @@ jobs:
116120
# the subsequent `run:` and `uses:` steps.
117121
118122
# Determine the name of a file containing the input of interest (that triggers the panic/crash):
119-
if [ -e $ARTIFACTS_RDPATH/$TARGET_NAME/crash-* ]; then # Panic and Stack Overflow Cases.
123+
if [ -e $ARTIFACTS_RDPATH/${{ matrix.target_name }}/crash-* ]; then # Panic and Stack Overflow Cases.
120124
TO_MINIMIZE_FNAME=crash-*;
121-
elif [ -e $ARTIFACTS_RDPATH/$TARGET_NAME/oom-* ]; then # Out-of-Memory Case.
125+
elif [ -e $ARTIFACTS_RDPATH/${{ matrix.target_name }}/oom-* ]; then # Out-of-Memory Case.
122126
TO_MINIMIZE_FNAME=oom-*;
123127
else
124-
echo -e "File to minimize not found.\nContents of artifacts dir \"$ARTIFACTS_RDPATH/$TARGET_NAME/\":"
125-
ls $ARTIFACTS_RDPATH/$TARGET_NAME/
128+
echo -e "File to minimize not found.\nContents of artifacts dir \"$ARTIFACTS_RDPATH/${{ matrix.target_name }}/\":"
129+
ls $ARTIFACTS_RDPATH/${{ matrix.target_name }}/
126130
fi
127131
128132
if [ "$TO_MINIMIZE_FNAME" != "" ]; then
129133
echo "TO_MINIMIZE_FNAME: $TO_MINIMIZE_FNAME"
130134
131135
# Minimize the input:
132-
( cargo fuzz tmin --release --sanitizer=none --features do_fuzz -r 10000 $TARGET_NAME $ARTIFACTS_RDPATH/$TARGET_NAME/$TO_MINIMIZE_FNAME 2>&1 ) > \
136+
( cargo fuzz tmin --release --sanitizer=none --features do_fuzz -r 10000 ${{ matrix.target_name }} $ARTIFACTS_RDPATH/${{ matrix.target_name }}/$TO_MINIMIZE_FNAME 2>&1 ) > \
133137
$TMIN_LOG_FNAME || MINIMIZATION_FAILED=1
134138
135139
# Get the minimized input relative faile path:
136140
if [ "$MINIMIZATION_FAILED" == "1" ]; then
137141
# Minimization failed, get the latest successful minimized input relative faile path:
138142
MINIMIZED_INPUT_RFPATH=`
139143
cat $TMIN_LOG_FNAME | grep "CRASH_MIN: minimizing crash input: " | tail -n 1 |
140-
sed "s|^.*\($ARTIFACTS_RDPATH/$TARGET_NAME/[^\']*\).*|\1|"`
144+
sed "s|^.*\($ARTIFACTS_RDPATH/${{ matrix.target_name }}/[^\']*\).*|\1|"`
141145
else
142146
# Minimization Succeeded, get the reported minimized input relative faile path::
143147
MINIMIZED_INPUT_RFPATH=`
144148
cat $TMIN_LOG_FNAME | grep "failed to minimize beyond" |
145-
sed "s|.*\($ARTIFACTS_RDPATH/$TARGET_NAME/[^ ]*\).*|\1|" `
149+
sed "s|.*\($ARTIFACTS_RDPATH/${{ matrix.target_name }}/[^ ]*\).*|\1|" `
146150
fi
147151
echo "MINIMIZED_INPUT_RFPATH: $MINIMIZED_INPUT_RFPATH"
148152
echo "MINIMIZED_INPUT_RFPATH=$MINIMIZED_INPUT_RFPATH" >> "$GITHUB_ENV"
@@ -187,8 +191,8 @@ jobs:
187191
path: |
188192
${{ env.OWNER_RDPATH }}/${{ env.STDERR_LOG_FNAME }}
189193
${{ env.OWNER_RDPATH }}/${{ env.TMIN_LOG_FNAME }}
190-
${{ env.OWNER_RDPATH }}/${{ env.ARTIFACTS_RDPATH }}/${{ env.TARGET_NAME }}/*
191-
${{ env.OWNER_RDPATH }}/${{ env.SEEDS_RDPATH }}/${{ env.TARGET_NAME }}/${{ env.SEEDS_FNAME }}
194+
${{ env.OWNER_RDPATH }}/${{ env.ARTIFACTS_RDPATH }}/${{ matrix.target_name }}/*
195+
${{ env.OWNER_RDPATH }}/${{ env.SEEDS_RDPATH }}/${{ matrix.target_name }}/${{ env.SEEDS_FNAME }}
192196
if-no-files-found: error
193197

194198
- name: "If Fuzzing Failed: Report GutHub Issue"

fuzz/Cargo.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@ do_fuzz = [ "dep:libfuzzer-sys" ]
2626
workspace = true
2727

2828
[[bin]]
29-
name = "compile"
30-
path = "fuzz_targets/compile.rs"
29+
name = "qsharp"
30+
path = "fuzz_targets/qsharp.rs"
31+
test = false
32+
doc = false
33+
34+
[[bin]]
35+
name = "qasm3"
36+
path = "fuzz_targets/qasm3.rs"
3137
test = false
3238
doc = false

fuzz/fuzz_targets/qasm3.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
#![no_main]
5+
6+
allocator::assign_global!();
7+
8+
#[cfg(feature = "do_fuzz")]
9+
use libfuzzer_sys::fuzz_target;
10+
11+
fn compile(data: &[u8]) {
12+
if let Ok(fuzzed_code) = std::str::from_utf8(data) {
13+
let resolver = qsc::qasm3::io::InMemorySourceResolver::from_iter([]);
14+
let _ = qsc::qasm3::parser::parse_source(fuzzed_code, "fuzz.qasm", &resolver);
15+
}
16+
}
17+
18+
#[cfg(feature = "do_fuzz")]
19+
fuzz_target!(|data: &[u8]| {
20+
compile(data);
21+
});
22+
23+
#[cfg(not(feature = "do_fuzz"))]
24+
#[no_mangle]
25+
pub extern "C" fn main() {
26+
compile(&[]);
27+
}
File renamed without changes.

fuzz/seed_inputs/compile/list.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

fuzz/seed_inputs/qasm3/input.qasm

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
OPENQASM 3;
2+
include "stdgates.inc";
3+
qubit q;
4+
qubit[2] q2;
5+
bit c;
6+
bit[2] c2;
7+
c2 = measure q2;
8+
c = measure q;

fuzz/seed_inputs/qasm3/list.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fuzz/seed_inputs/qasm3/input.qasm
File renamed without changes.

fuzz/seed_inputs/qsharp/list.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fuzz/seed_inputs/qsharp/input.qs

0 commit comments

Comments
 (0)