88 type : string
99 default : duckdb/duckdb
1010 ref :
11- description : ' ref '
11+ description : ' duckdb branch, tag, or full-length SHA '
1212 required : true
1313 type : string
14- default : 4ebeb16350eb2f819d682c581490af460dd0c995
14+ # oldest usable ref: 4ebeb16350eb2f819d682c581490af460dd0c995
15+ default : main
1516 fuzzer :
1617 description : ' fuzz scenario'
1718 required : true
5657 echo ${{ inputs.fuzzer }}
5758 echo ${{ inputs.fuzzTime }}
5859
60+ - name : define input dependent variables
61+ run : |
62+ case ${{ inputs.fuzzer }} in
63+ csv_multi_param_fuzzer)
64+ echo "CREATE_CORPUS_INFO_ARGS=read_csv $DUCKDB_DIR $DUCKDB_DIR/test" >> $GITHUB_ENV
65+ echo "CREATE_CORPUS_ARGS=read_csv $DUCKDB_DIR" >> $GITHUB_ENV
66+ echo "FILE_FORMAT=csv" >> $GITHUB_ENV
67+ ;;
68+ json_multi_param_fuzzer)
69+ echo "CREATE_CORPUS_INFO_ARGS=read_json $DUCKDB_DIR $DUCKDB_DIR/test" >> $GITHUB_ENV
70+ echo "CREATE_CORPUS_ARGS=read_json $DUCKDB_DIR" >> $GITHUB_ENV
71+ echo "FILE_FORMAT=json" >> $GITHUB_ENV
72+ ;;
73+ parquet_multi_param_fuzzer)
74+ echo "CREATE_CORPUS_INFO_ARGS=read_parquet $DUCKDB_DIR $DUCKDB_DIR/test" >> $GITHUB_ENV
75+ echo "CREATE_CORPUS_ARGS=read_parquet $DUCKDB_DIR" >> $GITHUB_ENV
76+ echo "FILE_FORMAT=parquet" >> $GITHUB_ENV
77+ ;;
78+ *)
79+ echo unsupported fuzzer
80+ exit 1
81+ ;;
82+ esac
83+
5984 # https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/INSTALL.md
6085 - name : Install AFL++ dependencies
6186 run : |
@@ -89,6 +114,16 @@ jobs:
89114 ref : ${{ inputs.ref }}
90115 path : duckdb
91116
117+ # /proc/sys/kernel/core_pattern needs to be adjusted, see:
118+ # https://github.com/AFLplusplus/AFLplusplus/blob/fb52b8edf86e12628df834f4bb144916b18a503d/src/afl-fuzz-init.c#L2476C1-L2489C70
119+ - name : Config step
120+ working-directory : ${{ env.DUCKDB_AFLPLUSPLUS_DIR }}
121+ run : |
122+ echo core | sudo tee /proc/sys/kernel/core_pattern
123+ mkdir -p build
124+ mkdir -p corpus
125+ mkdir -p fuzz_results
126+
92127 # https://github.com/AFLplusplus/AFLplusplus/blob/stable/GNUmakefile
93128 - name : Cache AFL++ binaries
94129 if : ${{ inputs.cacheAFL }}
@@ -109,8 +144,8 @@ jobs:
109144
110145 - name : build AFL++
111146 if : steps.cache-aflplusplus.outputs.cache-hit != 'true'
147+ working-directory : aflplusplus
112148 run : |
113- cd aflplusplus
114149 sudo make PREFIX=${{ github.workspace }} source-only
115150 sudo make PREFIX=${{ github.workspace }} install
116151
@@ -128,8 +163,7 @@ jobs:
128163
129164 - name : Compile DuckDB with afl++ compiler
130165 run : |
131- cd duckdb_aflplusplus/src
132- make \
166+ make -C $DUCKDB_AFLPLUSPLUS_DIR/src \
133167 DUCKDB_DIR=$DUCKDB_DIR \
134168 DUCKDB_AFLPLUSPLUS_DIR=$DUCKDB_AFLPLUSPLUS_DIR \
135169 CC=$CC \
@@ -139,8 +173,9 @@ jobs:
139173 duckdb-lib
140174
141175 - name : duckdb version
176+ working-directory : ${{ env.DUCKDB_DIR }}
142177 run : |
143- $DUCKDB_DIR /build/release/duckdb --version
178+ . /build/release/duckdb --version
144179
145180 # NOTE: duckdb-python is only used for pre and post processing; does not have to be compiled from source
146181 - name : Install duckdb python API
@@ -150,9 +185,7 @@ jobs:
150185
151186 - name : Compile Fuzz target
152187 run : |
153- mkdir -p $DUCKDB_AFLPLUSPLUS_DIR/build
154- cd $DUCKDB_AFLPLUSPLUS_DIR/src
155- make \
188+ make -C $DUCKDB_AFLPLUSPLUS_DIR/src \
156189 DUCKDB_DIR=$DUCKDB_DIR \
157190 DUCKDB_AFLPLUSPLUS_DIR=$DUCKDB_AFLPLUSPLUS_DIR \
158191 CC=$CC \
@@ -161,41 +194,40 @@ jobs:
161194 USE_CCACHE=1 \
162195 $DUCKDB_AFLPLUSPLUS_DIR/build/${{ inputs.fuzzer }}
163196
164- # todo: make generic for all fuzzers
165- - name : Create corpus - csv_multi_param_fuzzer
166- if : ${{ inputs.fuzzer == 'csv_multi_param_fuzzer' }}
197+ - name : Create corpus
198+ working-directory : ${{ env.DUCKDB_AFLPLUSPLUS_DIR }}
167199 run : |
168- ls -la $DUCKDB_AFLPLUSPLUS_DIR/scripts/corpus_creation/
169- chmod +x ./duckdb_aflplusplus/scripts/corpus_creation/create_multi_param_corpus_info.py
170- chmod +x ./duckdb_aflplusplus/scripts/corpus_creation/create_multi_param_corpus.py
171- $DUCKDB_AFLPLUSPLUS_DIR/scripts/corpus_creation/create_multi_param_corpus_info.py read_csv $DUCKDB_DIR $DUCKDB_DIR/test
172- $DUCKDB_AFLPLUSPLUS_DIR/scripts/corpus_creation/create_multi_param_corpus.py read_csv $DUCKDB_DIR
200+ chmod +x scripts/corpus_creation/create_multi_param_corpus_info.py
201+ chmod +x scripts/corpus_creation/create_multi_param_corpus.py
202+ ./scripts/corpus_creation/create_multi_param_corpus_info.py ${{ env.CREATE_CORPUS_INFO_ARGS }}
203+ ./scripts/corpus_creation/create_multi_param_corpus.py ${{ env.CREATE_CORPUS_ARGS }}
173204
174- # todo: make generic for all fuzzers
175- # /proc/sys/kernel/core_pattern needs to be adjusted, see:
176- # https://github.com/AFLplusplus/AFLplusplus/blob/fb52b8edf86e12628df834f4bb144916b18a503d/src/afl-fuzz-init.c#L2476C1-L2489C70
177- - name : Start fuzzing - fuzz_csv_multi_param
205+ - name : Start fuzzing
206+ working-directory : ${{ env.DUCKDB_AFLPLUSPLUS_DIR }}
178207 env :
179208 AFL_IGNORE_SEED_PROBLEMS : 1
180209 run : |
181- echo core | sudo tee /proc/sys/kernel/core_pattern
182- mkdir -p $DUCKDB_AFLPLUSPLUS_DIR/fuzz_results
183210 ${{ github.workspace }}/bin/afl-fuzz \
184211 -V ${{ inputs.fuzzTime }} \
185- -i $DUCKDB_AFLPLUSPLUS_DIR/corpus/csv /corpus_prepended \
212+ -i $DUCKDB_AFLPLUSPLUS_DIR/corpus/$FILE_FORMAT /corpus_prepended \
186213 -o $DUCKDB_AFLPLUSPLUS_DIR/fuzz_results/${{ inputs.fuzzer }} \
187214 -m none \
188215 -d \
189216 -- $DUCKDB_AFLPLUSPLUS_DIR/build/${{ inputs.fuzzer }}
190- cd $DUCKDB_AFLPLUSPLUS_DIR && tar -cvf ${{ github.workspace }}/fuzz_results.tar fuzz_results/${{ inputs.fuzzer }}
191-
192- - name : debug
193- run : |
194- which afl-fuzz || echo afl-fuzz not found
195- ls -la
217+ tar -cvf ${{ github.workspace }}/fuzz_results.tar fuzz_results/${{ inputs.fuzzer }}
196218
197219 - name : Store fuzz result as artifact
198220 uses : actions/upload-artifact@v4
199221 with :
200222 name : ${{ inputs.fuzzer }}-${{ github.run_id }}
201223 path : fuzz_results.tar
224+
225+ - name : Add summary statistics
226+ working-directory : ${{ env.DUCKDB_AFLPLUSPLUS_DIR }}
227+ run : |
228+ NUM_CRASHES=$(ls -l fuzz_results/${{ inputs.fuzzer }}/default/crashes | grep id: | wc -l | sed 's/ *//')
229+ NUM_HANGS=$(ls -l fuzz_results/${{ inputs.fuzzer }}/default/hangs | grep id: | wc -l | sed 's/ *//')
230+ NUM_QUEUE=$(ls -l fuzz_results/${{ inputs.fuzzer }}/default/queue | grep id: | wc -l | sed 's/ *//')
231+ echo "::notice::crahses found: $NUM_CRASHES"
232+ echo "::notice::hangs found: $NUM_HANGS"
233+ echo "::notice::queue length: $NUM_QUEUE"
0 commit comments