🐺️ Fuzzer #2334
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: 🐺️ Fuzzer | |
on: | |
push: | |
pull_request: | |
schedule: | |
- cron: '0 0 * * *' | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
# Global Cache Settings | |
env: | |
# TODO Poke qarmin to update Qarminer and stuff | |
GODOT_BASE_BRANCH: "4.2" | |
SCONS_CACHE_LIMIT: 4096 | |
GODOT_BINARY_NAME: godot.linuxbsd.editor.dev.x86_64.san | |
jobs: | |
module-compilation: | |
runs-on: "ubuntu-22.04" | |
name: Editor | |
steps: | |
# Clone Godot | |
- uses: actions/checkout@v4 | |
with: | |
repository: godotengine/godot | |
ref: ${{ env.GODOT_BASE_BRANCH }} | |
# Clone our module under the correct directory | |
- uses: actions/checkout@v4 | |
with: | |
path: modules/voxel | |
# Azure repositories are not reliable, we need to prevent azure giving us packages. | |
- name: Make apt sources.list use the default Ubuntu repositories | |
run: | | |
sudo rm -f /etc/apt/sources.list.d/* | |
sudo cp -f modules/voxel/misc/sources.list /etc/apt/sources.list | |
sudo apt-get update | |
# Install all packages (except scons) | |
- name: Configure dependencies | |
run: | | |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \ | |
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm scons \ | |
xvfb wget unzip | |
# Upload cache on completion and check it out now | |
- name: Load .scons_cache directory | |
id: fuzzer-cache | |
uses: actions/cache@v4 | |
with: | |
path: ${{github.workspace}}/.scons_cache/ | |
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} | |
restore-keys: | | |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} | |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} | |
${{github.job}}-${{env.GODOT_BASE_BRANCH}} | |
# Fix the issue of running out of disk space during Compilation stage | |
# Taken from here: https://github.com/orgs/community/discussions/26351#discussioncomment-3251595 | |
- name: Free disk space | |
run: | | |
sudo swapoff -a | |
sudo rm -f /swapfile | |
sudo apt-get clean | |
docker rmi $(docker image ls -aq) | |
df -h | |
# NO-PIE is for more detailed bactraces with line symbols | |
- name: Compilation | |
env: | |
SCONS_CACHE: ${{github.workspace}}/.scons_cache/ | |
run: | | |
# Helpful to test later code without needing to compile entire editor | |
#wget https://downloads.tuxfamily.org/godotengine/4.0/beta3/Godot_v4.0-beta3_linux.x86_64.zip -O a.zip | |
#unzip a.zip | |
#mkdir bin/ | |
#mv Godot_v4.0-beta3_linux.x86_64 bin/godot.linuxbsd.editor.dev.x86_64.san | |
scons target=editor use_ubsan=yes use_asan=yes linker=gold dev_build=yes CCFLAGS="-fpie" LINKFLAGS="-no-pie" | |
- uses: actions/upload-artifact@v4 | |
with: | |
name: godot-linux | |
path: | | |
bin/ | |
# Different step, to be able to repeat it if needed | |
fuzz-project: | |
runs-on: "ubuntu-22.04" | |
name: Fuzzer | |
needs: module-compilation | |
steps: | |
# Download binaries from | |
- name: Download Executed project | |
uses: actions/download-artifact@v4 | |
with: | |
name: godot-linux | |
path: bin | |
# Add execute bit to downloaded binary | |
- name: Download Executed project | |
run: | | |
chmod +x bin/godot.linuxbsd.editor.dev.x86_64.san | |
# Clone our module under the correct directory | |
- uses: actions/checkout@v4 | |
with: | |
path: modules/voxel | |
# Clone fuzzer | |
- name: Checkout Godot fuzzer backend | |
uses: actions/checkout@v4 | |
with: | |
repository: qarmin/Qarminer | |
# At the time of writing, qarmin did not put out later than 4.1 versions, but claims that it works with Godot versions up to 4.3+ | |
# See https://github.com/qarmin/Qarminer/issues/32 | |
ref: 4.1 | |
path: fuzzer | |
- name: Copy fuzzer settings | |
run: | | |
cp modules/voxel/misc/fuzzer_config.txt fuzzer/settings.txt | |
# Download, unzip and setup SwiftShader library | |
# See https://github.com/godotengine/regression-test-project/releases/tag/_ci-deps for details | |
- name: Download SwiftShader | |
if: ${{ matrix.tests }} | |
run: | | |
wget https://github.com/godotengine/regression-test-project/releases/download/_ci-deps/swiftshader-ubuntu20.04-20211002.zip | |
unzip swiftshader-ubuntu20.04-20211002.zip | |
curr="$(pwd)/libvk_swiftshader.so" | |
sed -i "s|PATH_TO_CHANGE|$curr|" vk_swiftshader_icd.json | |
# Download reproducer | |
- name: Download reproducer | |
run: | | |
wget -nv https://github.com/qarmin/Qarminer/releases/download/reproducer/find_minimal_godot_crash_0.1.0 -O reproducer | |
chmod +x ./reproducer | |
# 960 seconds - Hard timeout time, controlled by OS/timeout app | |
# 600 seconds - Timeout controlled by Fuzzer app(certain functions may freeze Godot, so this is not reliable method, so using also method from above with little bigger timeout value) | |
# FunctionsExectuor.tscn - Scene which tests almost all function of choosen classes | |
# UBSAN_OPTIONS - suppress false positives from thirdparty Godot libraries | |
# Reproducer options | |
# timeout -v 3600 - protection from timeout(should not happen anyway) | |
# arguments - should be same like in normal fuzzer run(without xvfb-run and scene) | |
# 60_50 - timeouts, 60 means 60s for single run, if this time exceed, that means that current scene timeouts, 50 means 50 minutes for all checking, if reproducer cannot find problem within this time, then returned is 0 status, because problem probably happens not regulary due e.g. big amount of checked functions | |
# HEADLESS | |
- name: Run fuzzer Headless | |
run: | | |
UBSAN_OPTIONS=suppressions=../modules/voxel/misc/suppressions.supp DRI_PRIME=0 timeout -v 960 xvfb-run bin/godot.linuxbsd.editor.dev.x86_64.san FunctionExecutor.tscn 600 --headless --path fuzzer 2>&1 | tee sanitizers_log.txt || true | |
tail -n 200 sanitizers_log.txt >> project_results.txt | |
- name: Copy results from fuzzer directory | |
run: | | |
mv fuzzer/results.txt . || true | |
mv fuzzer/CRASH_FOUND . || true | |
mv fuzzer/crash_reproduce.gd results.txt || true | |
- name: Run reproducer Headless | |
run: | | |
echo "extends Node" > temp.txt | |
echo "func _process(delta):" >> temp.txt | |
if [ -f results.txt ]; then | |
cat temp.txt results.txt > fuzzer/Node.gd.test || true | |
UBSAN_OPTIONS=suppressions=../modules/voxel/misc/suppressions.supp DRI_PRIME=0 timeout -v 3600 ./reproducer bin/godot.linuxbsd.editor.dev.x86_64.san 60_50 fuzzer --headless | |
fi | |
- name: Store reproducer Headless | |
uses: actions/upload-artifact@v4 | |
with: | |
name: reproducer_4_headless | |
path: crash_reproduce.gd | |
if-no-files-found: ignore | |
- name: Clear data before next run | |
run: | | |
echo "==================================" >> results_connected.txt || true | |
cat results.txt >> results_connected.txt || true | |
rm results.txt || true | |
rm crash_reproduce.gd || true | |
# GLES 3 | |
- name: Run fuzzer GLES3 | |
run: | | |
UBSAN_OPTIONS=suppressions=../modules/voxel/misc/suppressions.supp DRI_PRIME=0 timeout -v 960 xvfb-run bin/godot.linuxbsd.editor.dev.x86_64.san FunctionExecutor.tscn 600 --rendering-driver opengl3 --audio-driver Dummy --path fuzzer 2>&1 | tee sanitizers_log.txt || true | |
tail -n 200 sanitizers_log.txt >> project_results.txt | |
- name: Copy results from fuzzer directory | |
run: | | |
mv fuzzer/results.txt . || true | |
mv fuzzer/CRASH_FOUND . || true | |
mv fuzzer/crash_reproduce.gd results.txt || true | |
- name: Run reproducer GLES3 | |
run: | | |
echo "extends Node" > temp.txt | |
echo "func _process(delta):" >> temp.txt | |
if [ -f results.txt ]; then | |
cat temp.txt results.txt > fuzzer/Node.gd.test || true | |
UBSAN_OPTIONS=suppressions=../modules/voxel/misc/suppressions.supp DRI_PRIME=0 timeout -v 3600 ./reproducer bin/godot.linuxbsd.editor.dev.x86_64.san 60_50 fuzzer --rendering-driver opengl3 --audio-driver Dummy | |
fi | |
- name: Store reproducer Headless | |
uses: actions/upload-artifact@v4 | |
with: | |
name: reproducer_4_gles3 | |
path: crash_reproduce.gd | |
if-no-files-found: ignore | |
- name: Clear data before next run | |
run: | | |
echo "==================================" >> results_connected.txt || true | |
cat results.txt >> results_connected.txt || true | |
rm results.txt || true | |
rm crash_reproduce.gd || true | |
# Vulkan | |
- name: Run fuzzer Vulkan | |
run: | | |
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json UBSAN_OPTIONS=suppressions=../modules/voxel/misc/suppressions.supp DRI_PRIME=0 timeout -v 960 xvfb-run bin/godot.linuxbsd.editor.dev.x86_64.san FunctionExecutor.tscn 600 --rendering-driver opengl3 --audio-driver Dummy --path fuzzer 2>&1 | tee sanitizers_log.txt || true | |
tail -n 200 sanitizers_log.txt >> project_results.txt | |
- name: Copy results from fuzzer directory | |
run: | | |
mv fuzzer/results.txt . || true | |
mv fuzzer/CRASH_FOUND . || true | |
mv fuzzer/crash_reproduce.gd results.txt || true | |
- name: Run reproducer Vulkan | |
run: | | |
echo "extends Node" > temp.txt | |
echo "func _process(delta):" >> temp.txt | |
if [ -f results.txt ]; then | |
cat temp.txt results.txt > fuzzer/Node.gd.test || true | |
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json UBSAN_OPTIONS=suppressions=../modules/voxel/misc/suppressions.supp DRI_PRIME=0 timeout -v 3600 ./reproducer bin/godot.linuxbsd.editor.dev.x86_64.san 60_50 fuzzer --rendering-driver opengl3 --audio-driver Dummy | |
fi | |
- name: Store reproducer Vulkan | |
uses: actions/upload-artifact@v4 | |
with: | |
name: reproducer_4_vulkan | |
path: crash_reproduce.gd | |
if-no-files-found: ignore | |
- name: Clear data before next run | |
run: | | |
echo "==================================" >> results_connected.txt || true | |
cat results.txt >> results_connected.txt || true | |
rm results.txt || true | |
rm crash_reproduce.gd || true | |
- name: Store project results | |
uses: actions/upload-artifact@v4 | |
with: | |
name: project-results | |
path: project_results.txt | |
- name: Store last run functions | |
uses: actions/upload-artifact@v4 | |
with: | |
name: last-run-functions | |
path: results_connected.txt | |
- name: Check fuzzer output | |
run: | | |
modules/voxel/misc/check_ci_log.py sanitizers_log.txt |