Skip to content

Commit

Permalink
New harness (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
novafacing authored Mar 25, 2024
1 parent ac494cf commit 07a2b35
Show file tree
Hide file tree
Showing 94 changed files with 16,093 additions and 3,518 deletions.
2 changes: 1 addition & 1 deletion .github/builder/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ RUN yum -y update && \
coreutils \
gcc \
gcc-c++ \
make \
make && \
yum clean all

COPY .github/builder/rsrc/rustup-init /install/rustup-init
Expand Down
70 changes: 41 additions & 29 deletions .github/workflows/scans.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,36 +44,46 @@ jobs:
/action/lib/linter.sh || ( echo "❗ [CT222] Super linter found an issue (possibly Hadolint)" && exit 1 )
echo "✅ [CT222] Hadolint Dockerfile check passed"
scan_containers:
scan_x86_64_breakpoint_uefi_edk2_container:
runs-on: ubuntu-latest
strategy:
matrix:
dockerfile:
# NOTE: These containers exceed the GitHub size limit and must be scanned manually
# - Dockerfile
# - examples/manual-example/Dockerfile
# - modules/tsffs/tests/targets/minimal-riscv-64/Dockerfile
# - modules/tsffs/tests/targets/minimal-riscv-64-edk2/Dockerfile
- tests/rsrc/x86_64-breakpoint-uefi-edk2/Dockerfile
- tests/rsrc/x86_64-timeout-uefi-edk2/Dockerfile
- tests/rsrc/x86_64-uefi-edk2/Dockerfile
include:
# NOTE: These containers exceed the GitHub size limit and must be scanned manually
# - dockerfile: Dockerfile
# context: .
# - dockerfile: examples/manual-example/Dockerfile
# context: .
# - dockerfile: modules/tsffs/tests/targets/minimal-riscv-64/Dockerfile
# context: modules/tsffs/tests/targets/minimal-riscv-64/
# - dockerfile: modules/tsffs/tests/targets/minimal-riscv-64-edk2/Dockerfile
# context: modules/tsffs/tests/targets/minimal-riscv-64-edk2/
- dockerfile: tests/rsrc/x86_64-breakpoint-uefi-edk2/Dockerfile
context: tests/rsrc/x86_64-breakpoint-uefi-edk2/
- dockerfile: tests/rsrc/x86_64-timeout-uefi-edk2/Dockerfile
context: tests/rsrc/x86_64-timeout-uefi-edk2/
- dockerfile: tests/rsrc/x86_64-uefi-edk2/Dockerfile
context: tests/rsrc/x86_64-uefi-edk2/
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
lfs: false

- name: Build Image
run: |
cd tests/rsrc/x86_64-breakpoint-uefi-edk2/
cp "../../../harness/tsffs.h" "src/tsffs.h"
docker buildx build -t container -f Dockerfile . > build.log 2>&1 || { tail -n 1000 build.log; exit 1; }
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: container

scan_x86_64_timeout_uefi_edk2_container:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
lfs: false

- name: Build Image
run: |
cd tests/rsrc/x86_64-timeout-uefi-edk2/
cp "../../../harness/tsffs.h" "src/tsffs.h"
docker buildx build -t container -f Dockerfile . > build.log 2>&1 || { tail -n 1000 build.log; exit 1; }
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: container

scan_x86_64_uefi_edk2_container:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -82,7 +92,9 @@ jobs:

- name: Build Image
run: |
docker build -t container -f ${{ matrix.dockerfile }} ${{ matrix.context }}
cd tests/rsrc/x86_64-uefi-edk2/
cp "../../../harness/tsffs.h" "src/tsffs.h"
docker buildx build -t container -f Dockerfile . > build.log 2>&1 || { tail -n 1000 build.log; exit 1; }
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
Expand Down
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ version = "0.2.1"

[package.metadata.simics]
package-number = 31337
# version = "6.0.pre4"
version = "6.0.5"

version = "6.0.6"

[lib]
crate-type = ["cdylib", "rlib"]
Expand Down Expand Up @@ -71,6 +71,8 @@ serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.114"
versions = { version = "6.1.0", features = ["serde"] }
ffi = "0.1.1"
num-traits = "0.2.18"
num-derive = "0.4.2"
tracing-subscriber = "0.3.18"
tracing = { version = "0.1.40", features = ["log"] }

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ RUN ispm projects /workspace/projects/example/ --create \
cp /workspace/tsffs/examples/docker-example/fuzz.simics /workspace/projects/example/ && \
cp /workspace/tsffs/tests/rsrc/minimal_boot_disk.craff /workspace/projects/example/ && \
cp /workspace/tsffs/tests/rsrc/x86_64-uefi/* /workspace/projects/example/ && \
cp /workspace/tsffs/harness/tsffs-gcc-x86_64.h /workspace/projects/example/ && \
cp /workspace/tsffs/harness/tsffs.h /workspace/projects/example/ && \
ninja

RUN echo 'echo "To run the demo, run ./simics -no-gui --no-win fuzz.simics"' >> /root/.bashrc
Expand Down
99 changes: 95 additions & 4 deletions docs/src/config/common-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ is desired.
- [Using Snapshots](#using-snapshots)
- [Using CMPLog](#using-cmplog)
- [Set Corpus and Solutions Directory](#set-corpus-and-solutions-directory)
- [Enable and Set the Checkpoint Path](#enable-and-set-the-checkpoint-path)
- [Enable Random Corpus Generation](#enable-random-corpus-generation)
- [Set an Iteration Limit](#set-an-iteration-limit)
- [Adding Tokens From Target Software](#adding-tokens-from-target-software)
- [Setting an Architecture Hint](#setting-an-architecture-hint)
- [Adding a Trace Processor](#adding-a-trace-processor)
- [Disabling Coverage Reporting](#disabling-coverage-reporting)
- [Enable Logging and Set Log path](#enable-logging-and-set-log-path)
- [Keep All Corpus Entries](#keep-all-corpus-entries)
- [Use Initial Buffer Contents As Corpus](#use-initial-buffer-contents-as-corpus)

## Solution Configuration

Expand All @@ -36,6 +41,18 @@ Note that this timeout is in virtual time, not real time. This means that whethe
simulation runs faster or slower than real time, the timeout will be accurate to the
target software's execution speed.

The fuzzing executor also has a timeout, which runs in real time. This timeout
is intended to detect situations where the fuzzer reaches a broken state where
it is no longer able to iterate (e.g. the virtual time timeout is not working)
and stop. By default, this timeout is set to 60 seconds and resets each
iteration. Only iterations which take more than 60 seconds will trigger the
timeout, but some very large fuzzing cases could exceed this time. To increase
it, for example to set the timeout to 10 minutes:

```python
@tsffs.executor_timeout = 600
```

### Setting Exception Solutions

The primary way TSFFS detects bugs is via CPU exceptions that are raised, but should not
Expand Down Expand Up @@ -163,7 +180,25 @@ changed with:


```python
tsffs.solutions_directory = SIM_lookup_file("%simics%/other_solutions_directory")
@tsffs.solutions_directory = SIM_lookup_file("%simics%/other_solutions_directory")
```

### Enable and Set the Checkpoint Path

The fuzzer captures an on-disk checkpoint before starting fuzzing by default. On Simics
7 and higher, this increases the snapshot restore speed very significantly, so it should
only be disabled if required.

To disable this behavior, you can set:

```python
@tsffs.pre_snapshot_checkpoint = False
```

To set the path for the checkpoint, you can set:

```python
@tsffs.checkpoint_path = SIM_lookup_file("%simics%") + "/checkpoint.ckpt"
```

### Enable Random Corpus Generation
Expand All @@ -182,6 +217,14 @@ This can be enabled with:
@tsffs.generate_random_corpus = True
```

The size of the initial random corpus can be set via (note, larger random corpuses are
generally not useful and a real corpus matching the expected data format should be used
instead!):

```python
@tsffs.initial_random_corpus_size = 64
```

### Set an Iteration Limit

The fuzzer can be set to execute only a specific number of iterations before exiting.
Expand Down Expand Up @@ -249,7 +292,7 @@ running `i386` code in backward-compatibility mode.
An architecture hint can be set with:

```python
@tsffs.iface.tsffs.add_architecture_hint(qsp.mb.cpu0.core[0][0], "i386")
@tsffs.iface.config.add_architecture_hint(qsp.mb.cpu0.core[0][0], "i386")
```

### Adding a Trace Processor
Expand All @@ -259,5 +302,53 @@ to the [manual start API](../harnessing/closed-box.md) is traced during executio
code running on multiple cores, the additional cores can be added with:

```python
@tsffs.iface.tsffs.add_trace_processor(qsp.mb.cpu0.core[0][1])
```
@tsffs.iface.config.add_trace_processor(qsp.mb.cpu0.core[0][1])
```

### Disabling Coverage Reporting

By default, the fuzzer will report new interesting control flow edges. This is
normally useful to check the fuzzer's progress and ensure it is finding new
paths. However in some cases, output may not be needed, so coverage reporting
can be disabled with:

```python
@tsffs.coverage_reporting = False
```

### Enable Logging and Set Log path

By default, the fuzzer will log useful informational messages in JSON format to
a log in the project directory (`log.json`).

The path for this log can be set by setting:

```python
@tsffs.log_path = SIM_lookup_file("%simics%) + "/log.json"
```

You can also disable the logging completely with:

```python
@tsffs.log_to_file = False
```

### Keep All Corpus Entries

For debugging purposes, TSFFS can be set to keep *all* corpus entries, not just
corpus entries which cause interesting results. This generates a large number
of corpus files.

```python
@tsffs.keep_all_corpus = True
```

### Use Initial Buffer Contents As Corpus

When using compiled-in or manual harnessing, the initial contents of the
testcase
buffer can be used as a seed corpus entry. This can be enabled with:

```python
@tsffs.use_initial_as_corpus = True
```
5 changes: 1 addition & 4 deletions docs/src/developer/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ The easiest way to do this is by loading and using it in a script that does what
want. For example, early in development there was a bug when calling the interface
API.

```txt
@tsffs.iface.tsffs.set_corpus_directory("%simics%/corpus")
```

So this script was used to help debug:

Expand All @@ -19,7 +16,7 @@ tsffs.log-level 4
@import time
@print("Sleeping")
@time.sleep(30)
@tsffs.iface.tsffs.set_corpus_directory("%simics%/corpus")
# Call your API here
```

ALl this script does is sleep for 30 seconds, then call the API we care about. The 30
Expand Down
2 changes: 1 addition & 1 deletion docs/src/harnessing/closed-box.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The same code as before, with no harness:


```c
#include "tsffs-gcc-x86_64.h"
#include "tsffs.h"

int main() {
char buf[20];
Expand Down
Loading

0 comments on commit 07a2b35

Please sign in to comment.