1--- 2layout: default 3title: Continuous Integration 4parent: Getting started 5nav_order: 5 6permalink: /getting-started/continuous-integration/ 7--- 8 9# Continuous Integration 10 11OSS-Fuzz offers **CIFuzz**, a GitHub action/CI job that runs your fuzz targets 12on pull requests. This works similarly to running unit tests in CI. CIFuzz helps 13you find and fix bugs before they make it into your codebase. 14Currently, CIFuzz only supports projects hosted on GitHub. 15 16## How it works 17 18CIFuzz builds your project's fuzzers from the source at a particular 19pull request or commit. Then CIFuzz runs the fuzzers for a short amount of time. 20If CIFuzz finds a crash, CIFuzz reports the stacktrace, makes the crashing 21input available for download and the CI test fails (red X). 22 23If CIFuzz doesn't find a crash during the allotted time, the CI test passes 24(green check). If CIFuzz finds a crash, it reports the crash only if both of following are true: 25* The crash is reproducible (on the PR/commit build). 26* The crash does not occur on older OSS-Fuzz builds. (If the crash does occur 27 on older builds, then it was not introduced by the PR/commit 28 being tested.) 29 30If your project supports [OSS-Fuzz's code coverage]({{ site.baseurl }}/advanced-topics/code-coverage), 31CIFuzz only runs the fuzzers affected by a pull request/commit. 32Otherwise it will divide up the allotted fuzzing time (10 minutes by default) 33among all fuzzers in the project. 34 35CIFuzz uses 30 day old/public regressions and corpora from OSS-Fuzz. This makes 36fuzzing more effective and gives you regression testing for free. 37 38## Requirements 39 401. Your project must be integrated with OSS-Fuzz. 411. Your project is hosted on GitHub. 421. Your repository needs to be cloned with `git` in oss-fuzz Dockerfile (do not use `go get` or other methods) 43 44## Integrating into your repository 45 46You can integrate CIFuzz into your project using the following steps: 471. Create a `.github` directory in the root of your project. 481. Create a `workflows` directory inside of your `.github` directory. 491. Copy the example [`main.yml`](https://github.com/google/oss-fuzz/blob/master/infra/cifuzz/example_main.yml) 50file over from the OSS-Fuzz repository to the `workflows` directory. 511. Change the `oss-fuzz-project-name` value in `main.yml` from `example` to the name of your OSS-Fuzz project. It is **very important** that you use your OSS-Fuzz project name which is case sensitive. This name 52is the name of your project's subdirectory in the [`projects`](https://github.com/google/oss-fuzz/tree/master/projects) directory of OSS-Fuzz. 531. Set the value of `fuzz-seconds`. The longest time that the project maintainers are acceptable with should be used. This value should be at minimum 600 seconds and scale with project size. 54 55Your directory structure should look like the following: 56``` 57project 58|___ .github 59| |____ workflows 60| |____ main.yml 61|___ other-files 62``` 63 64main.yml for an example project: 65 66```yaml 67name: CIFuzz 68on: [pull_request] 69jobs: 70 Fuzzing: 71 runs-on: ubuntu-latest 72 steps: 73 - name: Build Fuzzers 74 id: build 75 uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master 76 with: 77 oss-fuzz-project-name: 'example' 78 language: c++ 79 - name: Run Fuzzers 80 uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master 81 with: 82 oss-fuzz-project-name: 'example' 83 language: c++ 84 fuzz-seconds: 600 85 - name: Upload Crash 86 uses: actions/upload-artifact@v1 87 if: failure() && steps.build.outcome == 'success' 88 with: 89 name: artifacts 90 path: ./out/artifacts 91``` 92 93 94### Optional configuration 95 96#### Configurable Variables 97 98`language`: (optional) The language your target program is written in. Defaults 99to `c++`. This should be the same as the value you set in `project.yaml`. See 100[this explanation]({{ site.baseurl }}//getting-started/new-project-guide/#language) 101for more details. 102 103`fuzz-time`: Determines how long CIFuzz spends fuzzing your project in seconds. 104The default is 600 seconds. The GitHub Actions max run time is 21600 seconds (6 105hours). This variable is only meaningful when supplied to the `run_fuzzers` 106action, not the `build_fuzzers` action. 107 108`dry-run`: Determines if CIFuzz surfaces errors. The default value is `false`. When set to `true`, 109CIFuzz will never report a failure even if it finds a crash in your project. 110This requires the user to manually check the logs for detected bugs. If dry run mode is desired, 111make sure to set the dry-run parameters in both the `Build Fuzzers` and `Run Fuzzers` action step. 112 113`allowed-broken-targets-percentage`: Can be set if you want to set a stricter 114limit for broken fuzz targets than OSS-Fuzz's check_build. Most users should 115not set this. This value is only meaningful when supplied to the `run_fuzzers` 116action, not the `build_fuzzers` action. 117 118`sanitizer`: Determines a sanitizer to build and run fuzz targets with. The choices are `'address'`, 119`'memory'` and `'undefined'`. The default is `'address'`. It is important to note that the `Build Fuzzers` 120and the `Run Fuzzers` sanitizer field needs to be the same. To specify a list of sanitizers 121a [matrix](https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix) 122can be used. To use a sanitizer add it to the list of sanitizers in the matrix field below: 123 124```yaml 125{% raw %} 126name: CIFuzz 127on: [pull_request] 128jobs: 129 Fuzzing: 130 runs-on: ubuntu-latest 131 strategy: 132 fail-fast: false 133 matrix: 134 sanitizer: [address, undefined, memory] 135 steps: 136 - name: Build Fuzzers (${{ matrix.sanitizer }}) 137 id: build 138 uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master 139 with: 140 oss-fuzz-project-name: 'example' 141 language: c++ 142 sanitizer: ${{ matrix.sanitizer }} 143 - name: Run Fuzzers (${{ matrix.sanitizer }}) 144 uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master 145 with: 146 oss-fuzz-project-name: 'example' 147 language: c++ 148 fuzz-seconds: 600 149 sanitizer: ${{ matrix.sanitizer }} 150 - name: Upload Crash 151 uses: actions/upload-artifact@v1 152 if: failure() && steps.build.outcome == 'success' 153 with: 154 name: ${{ matrix.sanitizer }}-artifacts 155 path: ./out/artifacts 156{% endraw %} 157``` 158 159#### Branches and paths 160 161You can make CIFuzz trigger only on certain branches or paths by following the 162instructions [here](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions). 163For example, the following code can used to trigger CIFuzz only on changes to 164C/C++ code residing on master and release branches: 165 166```yaml 167name: CIFuzz 168on: 169 pull_request: 170 branches: 171 - master 172 - 'releases/**' 173 paths: 174 - '**.c' 175 - '**.cc' 176 - '**.cpp' 177 - '**.cxx' 178 - '**.h' 179jobs: 180 Fuzzing: 181 runs-on: ubuntu-latest 182 steps: 183 - name: Build Fuzzers 184 id: build 185 uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master 186 with: 187 oss-fuzz-project-name: 'example' 188 language: c++ 189 - name: Run Fuzzers 190 uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master 191 with: 192 oss-fuzz-project-name: 'example' 193 language: c++ 194 fuzz-seconds: 600 195 - name: Upload Crash 196 uses: actions/upload-artifact@v1 197 if: failure() && steps.build.outcome == 'success' 198 with: 199 name: artifacts 200 path: ./out/artifacts 201``` 202 203You can checkout CIFuzz configs for OSS-Fuzz projects. Example - 204[systemd](https://github.com/systemd/systemd/blob/master/.github/workflows/cifuzz.yml), 205[curl](https://github.com/curl/curl/blob/master/.github/workflows/fuzz.yml). 206 207## Understanding results 208 209The results of CIFuzz can be found in two different places. 210 211* Run fuzzers log: 212 1. This log can be accessed in the `actions` tab of a CIFuzz integrated repo. 213 1. Click on the `CIFuzz` button in the workflow selector on the left hand side. 214 1. Click on the event triggered by your desired pull request. 215 1. Click the `Fuzzing` workflow. 216 1. Select the `Run Fuzzer` drop down. It should show the timestamps and results 217 from each of the fuzz targets. 218 219 220 221 222* Artifacts: 223 1. When a crash is found by CIFuzz the Upload Artifact event is triggered. 224 1. This will cause a pop up in the right hand corner, allowing 225 you to download a zip file called `artifacts`. 226 1. `artifacts` contains two files for each crash: 227 * A test case that can be used to reproduce the crash. 228 * The sanitizer stack trace of the crash. 229 230 231 232 233## Feedback/Questions/Issues 234 235Create an issue in [OSS-Fuzz](https://github.com/google/oss-fuzz/issues/new) if you have questions or any other feedback on CIFuzz. 236