Skip to content

Commit 07a2b35

Browse files
authored
New harness (#69)
1 parent ac494cf commit 07a2b35

File tree

94 files changed

+16093
-3518
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+16093
-3518
lines changed

.github/builder/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ RUN yum -y update && \
88
coreutils \
99
gcc \
1010
gcc-c++ \
11-
make \
11+
make && \
1212
yum clean all
1313

1414
COPY .github/builder/rsrc/rustup-init /install/rustup-init

.github/workflows/scans.yml

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,36 +44,46 @@ jobs:
4444
/action/lib/linter.sh || ( echo "❗ [CT222] Super linter found an issue (possibly Hadolint)" && exit 1 )
4545
echo "✅ [CT222] Hadolint Dockerfile check passed"
4646
47-
scan_containers:
47+
scan_x86_64_breakpoint_uefi_edk2_container:
4848
runs-on: ubuntu-latest
49-
strategy:
50-
matrix:
51-
dockerfile:
52-
# NOTE: These containers exceed the GitHub size limit and must be scanned manually
53-
# - Dockerfile
54-
# - examples/manual-example/Dockerfile
55-
# - modules/tsffs/tests/targets/minimal-riscv-64/Dockerfile
56-
# - modules/tsffs/tests/targets/minimal-riscv-64-edk2/Dockerfile
57-
- tests/rsrc/x86_64-breakpoint-uefi-edk2/Dockerfile
58-
- tests/rsrc/x86_64-timeout-uefi-edk2/Dockerfile
59-
- tests/rsrc/x86_64-uefi-edk2/Dockerfile
60-
include:
61-
# NOTE: These containers exceed the GitHub size limit and must be scanned manually
62-
# - dockerfile: Dockerfile
63-
# context: .
64-
# - dockerfile: examples/manual-example/Dockerfile
65-
# context: .
66-
# - dockerfile: modules/tsffs/tests/targets/minimal-riscv-64/Dockerfile
67-
# context: modules/tsffs/tests/targets/minimal-riscv-64/
68-
# - dockerfile: modules/tsffs/tests/targets/minimal-riscv-64-edk2/Dockerfile
69-
# context: modules/tsffs/tests/targets/minimal-riscv-64-edk2/
70-
- dockerfile: tests/rsrc/x86_64-breakpoint-uefi-edk2/Dockerfile
71-
context: tests/rsrc/x86_64-breakpoint-uefi-edk2/
72-
- dockerfile: tests/rsrc/x86_64-timeout-uefi-edk2/Dockerfile
73-
context: tests/rsrc/x86_64-timeout-uefi-edk2/
74-
- dockerfile: tests/rsrc/x86_64-uefi-edk2/Dockerfile
75-
context: tests/rsrc/x86_64-uefi-edk2/
49+
steps:
50+
- uses: actions/checkout@v4
51+
with:
52+
fetch-depth: 0
53+
lfs: false
54+
55+
- name: Build Image
56+
run: |
57+
cd tests/rsrc/x86_64-breakpoint-uefi-edk2/
58+
cp "../../../harness/tsffs.h" "src/tsffs.h"
59+
docker buildx build -t container -f Dockerfile . > build.log 2>&1 || { tail -n 1000 build.log; exit 1; }
7660
61+
- name: Run Trivy vulnerability scanner
62+
uses: aquasecurity/trivy-action@master
63+
with:
64+
image-ref: container
65+
66+
scan_x86_64_timeout_uefi_edk2_container:
67+
runs-on: ubuntu-latest
68+
steps:
69+
- uses: actions/checkout@v4
70+
with:
71+
fetch-depth: 0
72+
lfs: false
73+
74+
- name: Build Image
75+
run: |
76+
cd tests/rsrc/x86_64-timeout-uefi-edk2/
77+
cp "../../../harness/tsffs.h" "src/tsffs.h"
78+
docker buildx build -t container -f Dockerfile . > build.log 2>&1 || { tail -n 1000 build.log; exit 1; }
79+
80+
- name: Run Trivy vulnerability scanner
81+
uses: aquasecurity/trivy-action@master
82+
with:
83+
image-ref: container
84+
85+
scan_x86_64_uefi_edk2_container:
86+
runs-on: ubuntu-latest
7787
steps:
7888
- uses: actions/checkout@v4
7989
with:
@@ -82,7 +92,9 @@ jobs:
8292

8393
- name: Build Image
8494
run: |
85-
docker build -t container -f ${{ matrix.dockerfile }} ${{ matrix.context }}
95+
cd tests/rsrc/x86_64-uefi-edk2/
96+
cp "../../../harness/tsffs.h" "src/tsffs.h"
97+
docker buildx build -t container -f Dockerfile . > build.log 2>&1 || { tail -n 1000 build.log; exit 1; }
8698
8799
- name: Run Trivy vulnerability scanner
88100
uses: aquasecurity/trivy-action@master

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ version = "0.2.1"
2121

2222
[package.metadata.simics]
2323
package-number = 31337
24-
# version = "6.0.pre4"
25-
version = "6.0.5"
24+
25+
version = "6.0.6"
2626

2727
[lib]
2828
crate-type = ["cdylib", "rlib"]
@@ -71,6 +71,8 @@ serde = { version = "1.0.197", features = ["derive"] }
7171
serde_json = "1.0.114"
7272
versions = { version = "6.1.0", features = ["serde"] }
7373
ffi = "0.1.1"
74+
num-traits = "0.2.18"
75+
num-derive = "0.4.2"
7476
tracing-subscriber = "0.3.18"
7577
tracing = { version = "0.1.40", features = ["log"] }
7678

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ RUN ispm projects /workspace/projects/example/ --create \
119119
cp /workspace/tsffs/examples/docker-example/fuzz.simics /workspace/projects/example/ && \
120120
cp /workspace/tsffs/tests/rsrc/minimal_boot_disk.craff /workspace/projects/example/ && \
121121
cp /workspace/tsffs/tests/rsrc/x86_64-uefi/* /workspace/projects/example/ && \
122-
cp /workspace/tsffs/harness/tsffs-gcc-x86_64.h /workspace/projects/example/ && \
122+
cp /workspace/tsffs/harness/tsffs.h /workspace/projects/example/ && \
123123
ninja
124124

125125
RUN echo 'echo "To run the demo, run ./simics -no-gui --no-win fuzz.simics"' >> /root/.bashrc

docs/src/config/common-options.md

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ is desired.
1212
- [Using Snapshots](#using-snapshots)
1313
- [Using CMPLog](#using-cmplog)
1414
- [Set Corpus and Solutions Directory](#set-corpus-and-solutions-directory)
15+
- [Enable and Set the Checkpoint Path](#enable-and-set-the-checkpoint-path)
1516
- [Enable Random Corpus Generation](#enable-random-corpus-generation)
1617
- [Set an Iteration Limit](#set-an-iteration-limit)
1718
- [Adding Tokens From Target Software](#adding-tokens-from-target-software)
1819
- [Setting an Architecture Hint](#setting-an-architecture-hint)
1920
- [Adding a Trace Processor](#adding-a-trace-processor)
21+
- [Disabling Coverage Reporting](#disabling-coverage-reporting)
22+
- [Enable Logging and Set Log path](#enable-logging-and-set-log-path)
23+
- [Keep All Corpus Entries](#keep-all-corpus-entries)
24+
- [Use Initial Buffer Contents As Corpus](#use-initial-buffer-contents-as-corpus)
2025

2126
## Solution Configuration
2227

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

44+
The fuzzing executor also has a timeout, which runs in real time. This timeout
45+
is intended to detect situations where the fuzzer reaches a broken state where
46+
it is no longer able to iterate (e.g. the virtual time timeout is not working)
47+
and stop. By default, this timeout is set to 60 seconds and resets each
48+
iteration. Only iterations which take more than 60 seconds will trigger the
49+
timeout, but some very large fuzzing cases could exceed this time. To increase
50+
it, for example to set the timeout to 10 minutes:
51+
52+
```python
53+
@tsffs.executor_timeout = 600
54+
```
55+
3956
### Setting Exception Solutions
4057

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

164181

165182
```python
166-
tsffs.solutions_directory = SIM_lookup_file("%simics%/other_solutions_directory")
183+
@tsffs.solutions_directory = SIM_lookup_file("%simics%/other_solutions_directory")
184+
```
185+
186+
### Enable and Set the Checkpoint Path
187+
188+
The fuzzer captures an on-disk checkpoint before starting fuzzing by default. On Simics
189+
7 and higher, this increases the snapshot restore speed very significantly, so it should
190+
only be disabled if required.
191+
192+
To disable this behavior, you can set:
193+
194+
```python
195+
@tsffs.pre_snapshot_checkpoint = False
196+
```
197+
198+
To set the path for the checkpoint, you can set:
199+
200+
```python
201+
@tsffs.checkpoint_path = SIM_lookup_file("%simics%") + "/checkpoint.ckpt"
167202
```
168203

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

220+
The size of the initial random corpus can be set via (note, larger random corpuses are
221+
generally not useful and a real corpus matching the expected data format should be used
222+
instead!):
223+
224+
```python
225+
@tsffs.initial_random_corpus_size = 64
226+
```
227+
185228
### Set an Iteration Limit
186229

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

251294
```python
252-
@tsffs.iface.tsffs.add_architecture_hint(qsp.mb.cpu0.core[0][0], "i386")
295+
@tsffs.iface.config.add_architecture_hint(qsp.mb.cpu0.core[0][0], "i386")
253296
```
254297

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

261304
```python
262-
@tsffs.iface.tsffs.add_trace_processor(qsp.mb.cpu0.core[0][1])
263-
```
305+
@tsffs.iface.config.add_trace_processor(qsp.mb.cpu0.core[0][1])
306+
```
307+
308+
### Disabling Coverage Reporting
309+
310+
By default, the fuzzer will report new interesting control flow edges. This is
311+
normally useful to check the fuzzer's progress and ensure it is finding new
312+
paths. However in some cases, output may not be needed, so coverage reporting
313+
can be disabled with:
314+
315+
```python
316+
@tsffs.coverage_reporting = False
317+
```
318+
319+
### Enable Logging and Set Log path
320+
321+
By default, the fuzzer will log useful informational messages in JSON format to
322+
a log in the project directory (`log.json`).
323+
324+
The path for this log can be set by setting:
325+
326+
```python
327+
@tsffs.log_path = SIM_lookup_file("%simics%) + "/log.json"
328+
```
329+
330+
You can also disable the logging completely with:
331+
332+
```python
333+
@tsffs.log_to_file = False
334+
```
335+
336+
### Keep All Corpus Entries
337+
338+
For debugging purposes, TSFFS can be set to keep *all* corpus entries, not just
339+
corpus entries which cause interesting results. This generates a large number
340+
of corpus files.
341+
342+
```python
343+
@tsffs.keep_all_corpus = True
344+
```
345+
346+
### Use Initial Buffer Contents As Corpus
347+
348+
When using compiled-in or manual harnessing, the initial contents of the
349+
testcase
350+
buffer can be used as a seed corpus entry. This can be enabled with:
351+
352+
```python
353+
@tsffs.use_initial_as_corpus = True
354+
```

docs/src/developer/debugging.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ The easiest way to do this is by loading and using it in a script that does what
66
want. For example, early in development there was a bug when calling the interface
77
API.
88

9-
```txt
10-
@tsffs.iface.tsffs.set_corpus_directory("%simics%/corpus")
11-
```
129

1310
So this script was used to help debug:
1411

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

2522
ALl this script does is sleep for 30 seconds, then call the API we care about. The 30

docs/src/harnessing/closed-box.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ The same code as before, with no harness:
1414

1515

1616
```c
17-
#include "tsffs-gcc-x86_64.h"
17+
#include "tsffs.h"
1818

1919
int main() {
2020
char buf[20];

0 commit comments

Comments
 (0)