Skip to content

Commit be12f76

Browse files
authored
Merge branch 'main' into remove-unused-deps
2 parents 4ae3e70 + 1932562 commit be12f76

File tree

5 files changed

+316
-0
lines changed

5 files changed

+316
-0
lines changed

.github/workflows/fuzzer.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: "Fuzzer Workflow"
2+
on:
3+
schedule:
4+
# At the end of every day
5+
- cron: "0 0 * * *"
6+
jobs:
7+
changelog:
8+
runs-on: ubuntu-latest
9+
steps:
10+
11+
- name: Checkout
12+
uses: actions/checkout@v3
13+
with:
14+
ref: ${{ github.head_ref }}
15+
16+
17+
- name: Cache Inputs
18+
id: cache-inputs
19+
uses: actions/cache@v3
20+
with:
21+
# Path where the inputs for the fuzzer are stored
22+
path: fuzzer/hfuzz_workspace/fuzz_json/input
23+
key: ${{ runner.os }}-inputs
24+
25+
26+
- name: Install dependencies
27+
run: |
28+
sudo apt-get update
29+
sudo apt-get install -y build-essential
30+
sudo apt-get install binutils-dev
31+
sudo apt-get install libunwind-dev
32+
sudo curl https://sh.rustup.rs -sSf | bash -s -- -y --default-toolchain nightly
33+
34+
- name: Set Environment Variable
35+
run: echo "PATH="/root/.cargo/bin:${PATH}"" >> $GITHUB_ENV
36+
37+
- name: Install Honggfuzz
38+
run: cargo install honggfuzz
39+
40+
- if: ${{ steps.cache-inputs.outputs.cache-hit != 'true' }}
41+
# If didn´t have any inputs starts from 0
42+
name: Initializing fuzzer from 0
43+
run: |
44+
cd fuzzer
45+
HFUZZ_RUN_ARGS="--dict=json.dict --run_time 10800 --timeout 60 -T" cargo hfuzz run fuzz_json
46+
47+
# If has cached inputs starts with them and run with minimize
48+
- if: ${{ steps.cache-inputs.outputs.cache-hit != 'false' }}
49+
name: Initializing fuzzer with previous inputs
50+
run: |
51+
cd fuzzer
52+
HFUZZ_RUN_ARGS="--dict=json.dict --run_time 10800 --minimize --timeout 60 -T" cargo hfuzz run fuzz_json
53+
54+
- uses: stefanzweifel/git-auto-commit-action@v4
55+
with:
56+
commit_message: changing report
57+
file_pattern: '*/hfuzz_workspace/fuzzer/fuzz_json/HONGGFUZZ* */hfuzz_workspace/fuzzer/fuzz_json/SIG*'

fuzzer/Cargo.toml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[package]
2+
name = "fuzzer"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
arbitrary = { version = "1.3.0", features = ["derive"] }
10+
honggfuzz = "0.5.55"
11+
bincode = { version = "2.0.0-rc.2", tag = "v2.0.0-rc.2", git = "https://github.com/bincode-org/bincode.git" }
12+
cairo-vm = { path = "../vm" }
13+
mimalloc = { version = "0.1.29", default-features = false, optional = true }
14+
nom = "7"
15+
thiserror = { version = "1.0.32" }
16+
17+
[dev-dependencies]
18+
assert_matches = "1.5.0"
19+
rstest = "0.17.0"
20+
21+
[workspace]
22+
members = ["."]
23+
24+
[features]
25+
default = ["with_mimalloc"]
26+
with_mimalloc = ["cairo-vm/with_mimalloc", "mimalloc"]
27+
28+
[[bin]]
29+
name = "fuzz_json"
30+
path = "src/fuzz_json.rs"

fuzzer/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## fuzz_json
2+
This fuzzer creates a json file directly from bytes.
3+
`HFUZZ_RUN_ARGS="--dict=json.dict" cargo hfuzz run fuzz_json`

fuzzer/json.dict

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#
2+
# AFL dictionary for JSON
3+
# -----------------------
4+
#
5+
# Just the very basics.
6+
#
7+
# Inspired by a dictionary by Jakub Wilk <[email protected]>
8+
#
9+
10+
"0"
11+
",0"
12+
":0"
13+
"0:"
14+
"-1.2e+3"
15+
16+
"true"
17+
"false"
18+
"null"
19+
20+
"\"\""
21+
",\"\""
22+
":\"\""
23+
"\"\":"
24+
25+
"{}"
26+
",{}"
27+
":{}"
28+
"{\"\":0}"
29+
"{{}}"
30+
31+
"[]"
32+
",[]"
33+
":[]"
34+
"[0]"
35+
"[[]]"
36+
37+
"''"
38+
"\\"
39+
"\\b"
40+
"\\f"
41+
"\\n"
42+
"\\r"
43+
"\\t"
44+
"\\u0000"
45+
"\\x00"
46+
"\\0"
47+
"\\uD800\\uDC00"
48+
"\\uDBFF\\uDFFF"
49+
50+
"\"\":0"
51+
"//"
52+
"/**/"
53+
54+
"$ref"
55+
"type"
56+
"coordinates"
57+
"@context"
58+
"@id"
59+
60+
","
61+
":"

fuzzer/src/fuzz_json.rs

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
use arbitrary::Arbitrary;
2+
use bincode::enc::write::Writer;
3+
use cairo_vm::cairo_run::{self, EncodeTraceError};
4+
use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor;
5+
use cairo_vm::vm::errors::cairo_run_errors::CairoRunError;
6+
use cairo_vm::vm::errors::trace_errors::TraceError;
7+
use cairo_vm::vm::errors::vm_errors::VirtualMachineError;
8+
use honggfuzz::fuzz;
9+
use std::fmt;
10+
use std::io::{self, Write};
11+
use std::path::PathBuf;
12+
use thiserror::Error;
13+
14+
#[cfg(feature = "with_mimalloc")]
15+
use mimalloc::MiMalloc;
16+
17+
#[cfg(feature = "with_mimalloc")]
18+
#[global_allocator]
19+
static ALLOC: MiMalloc = MiMalloc;
20+
21+
#[derive(Debug, Arbitrary)]
22+
struct Args {
23+
program_content: Vec<u8>,
24+
trace_file: Option<PathBuf>,
25+
print_output: bool,
26+
entrypoint: String,
27+
memory_file: Option<PathBuf>,
28+
layout: Layout,
29+
proof_mode: bool,
30+
secure_run: Option<bool>,
31+
}
32+
33+
#[derive(Debug, Arbitrary)]
34+
enum Layout {
35+
Plain,
36+
Small,
37+
Dex,
38+
Starknet,
39+
StarknetWithKeccak,
40+
RecursiveLargeOutput,
41+
AllCairo,
42+
AllSolidity,
43+
Dynamic,
44+
}
45+
46+
impl fmt::Display for Layout {
47+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48+
match self {
49+
Layout::Plain => write!(f, "plain"),
50+
Layout::Small => write!(f, "small"),
51+
Layout::Dex => write!(f, "dex"),
52+
Layout::Starknet => write!(f, "starknet"),
53+
Layout::StarknetWithKeccak => write!(f, "starknet_with_keccak"),
54+
Layout::RecursiveLargeOutput => write!(f, "recursive_large_output"),
55+
Layout::AllCairo => write!(f, "all_cairo"),
56+
Layout::AllSolidity => write!(f, "all_solidity"),
57+
Layout::Dynamic => write!(f, "dynamic"),
58+
}
59+
}
60+
}
61+
62+
#[derive(Debug, Error)]
63+
enum Error {
64+
#[error("Failed to interact with the file system")]
65+
IO(#[from] std::io::Error),
66+
#[error("The cairo program execution failed")]
67+
Runner(#[from] CairoRunError),
68+
#[error(transparent)]
69+
EncodeTrace(#[from] EncodeTraceError),
70+
#[error(transparent)]
71+
VirtualMachine(#[from] VirtualMachineError),
72+
#[error(transparent)]
73+
Trace(#[from] TraceError),
74+
}
75+
76+
struct FileWriter {
77+
buf_writer: io::BufWriter<std::fs::File>,
78+
bytes_written: usize,
79+
}
80+
81+
impl Writer for FileWriter {
82+
fn write(&mut self, bytes: &[u8]) -> Result<(), bincode::error::EncodeError> {
83+
self.buf_writer
84+
.write_all(bytes)
85+
.map_err(|e| bincode::error::EncodeError::Io {
86+
inner: e,
87+
index: self.bytes_written,
88+
})?;
89+
90+
self.bytes_written += bytes.len();
91+
92+
Ok(())
93+
}
94+
}
95+
96+
impl FileWriter {
97+
fn new(buf_writer: io::BufWriter<std::fs::File>) -> Self {
98+
Self {
99+
buf_writer,
100+
bytes_written: 0,
101+
}
102+
}
103+
104+
fn flush(&mut self) -> io::Result<()> {
105+
self.buf_writer.flush()
106+
}
107+
}
108+
109+
fn run(args: Args) -> Result<(), Error> {
110+
let trace_enabled = args.trace_file.is_some();
111+
let mut hint_executor = BuiltinHintProcessor::new_empty();
112+
let cairo_run_config = cairo_run::CairoRunConfig {
113+
entrypoint: &args.entrypoint,
114+
trace_enabled,
115+
relocate_mem: args.memory_file.is_some(),
116+
layout: &args.layout.to_string(),
117+
proof_mode: args.proof_mode,
118+
secure_run: args.secure_run,
119+
};
120+
121+
let (cairo_runner, mut vm) =
122+
match cairo_run::cairo_run(&args.program_content, &cairo_run_config, &mut hint_executor) {
123+
Ok(runner) => runner,
124+
Err(error) => {
125+
eprintln!("{error}");
126+
return Err(Error::Runner(error));
127+
}
128+
};
129+
130+
if args.print_output {
131+
let mut output_buffer = "Program Output:\n".to_string();
132+
vm.write_output(&mut output_buffer)?;
133+
print!("{output_buffer}");
134+
}
135+
136+
if let Some(trace_path) = args.trace_file {
137+
let relocated_trace = vm.get_relocated_trace()?;
138+
139+
let trace_file = std::fs::File::create(trace_path)?;
140+
let mut trace_writer =
141+
FileWriter::new(io::BufWriter::with_capacity(3 * 1024 * 1024, trace_file));
142+
143+
cairo_run::write_encoded_trace(relocated_trace, &mut trace_writer)?;
144+
trace_writer.flush()?;
145+
}
146+
147+
if let Some(memory_path) = args.memory_file {
148+
let memory_file = std::fs::File::create(memory_path)?;
149+
let mut memory_writer =
150+
FileWriter::new(io::BufWriter::with_capacity(5 * 1024 * 1024, memory_file));
151+
152+
cairo_run::write_encoded_memory(&cairo_runner.relocated_memory, &mut memory_writer)?;
153+
memory_writer.flush()?;
154+
}
155+
156+
Ok(())
157+
}
158+
159+
fn main() {
160+
loop {
161+
fuzz!(|args: Args| {
162+
let _ = run(args);
163+
});
164+
}
165+
}

0 commit comments

Comments
 (0)