Skip to content

Commit 0094812

Browse files
authored
Update fuzzing test to check for simpleguest in same directory as executable (#324)
* Adding simple_guest_for_fuzzing_as_string() to hyperlight_testing Signed-off-by: Mark Rossett <[email protected]> * Updating fuzzing targets to use simple_guest_for_fuzzing_as_string Signed-off-by: Mark Rossett <[email protected]> * renaming fuzz targets to start with fuzz_ Signed-off-by: Mark Rossett <[email protected]> --------- Signed-off-by: Mark Rossett <[email protected]>
1 parent 2d2ea79 commit 0094812

File tree

9 files changed

+44
-12
lines changed

9 files changed

+44
-12
lines changed

.github/workflows/Fuzzing.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ jobs:
1313
fuzzing:
1414
uses: ./.github/workflows/dep_fuzzing.yml
1515
with:
16-
targets: '["host_print", "guest_call", "host_call"]' # Pass as a JSON array
16+
targets: '["fuzz_host_print", "fuzz_guest_call", "fuzz_host_call"]' # Pass as a JSON array
1717
max_total_time: 18000 # 5 hours in seconds
1818
secrets: inherit

.github/workflows/ValidatePullRequest.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
- docs-pr
5555
uses: ./.github/workflows/dep_fuzzing.yml
5656
with:
57-
targets: '["host_print", "guest_call", "host_call"]' # Pass as a JSON array
57+
targets: '["fuzz_host_print", "fuzz_guest_call", "fuzz_host_call"]' # Pass as a JSON array
5858
max_total_time: 300 # 5 minutes in seconds
5959
docs_only: ${{needs.docs-pr.outputs.docs-only}}
6060
secrets: inherit

Justfile

+7
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,10 @@ fuzz fuzz-target:
198198
# Fuzzes the given target. Stops after `max_time` seconds
199199
fuzz-timed fuzz-target max_time:
200200
cargo +nightly fuzz run {{ fuzz-target }} --release -- -max_total_time={{ max_time }}
201+
202+
# Builds fuzzers for submission to external fuzzing services
203+
build-fuzzers: (build-fuzzer "fuzz_guest_call") (build-fuzzer "fuzz_host_call") (build-fuzzer "fuzz_host_print")
204+
205+
# Builds the given fuzzer
206+
build-fuzzer fuzz-target:
207+
cargo +nightly fuzz build {{ fuzz-target }} --release -s none

fuzz/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,21 @@ hyperlight-testing = { workspace = true }
1313
hyperlight-host = { workspace = true, default-features = true, features = ["fuzzing"]}
1414

1515
[[bin]]
16-
name = "host_print"
16+
name = "fuzz_host_print"
1717
path = "fuzz_targets/host_print.rs"
1818
test = false
1919
doc = false
2020
bench = false
2121

2222
[[bin]]
23-
name = "guest_call"
23+
name = "fuzz_guest_call"
2424
path = "fuzz_targets/guest_call.rs"
2525
test = false
2626
doc = false
2727
bench = false
2828

2929
[[bin]]
30-
name = "host_call"
30+
name = "fuzz_host_call"
3131
path = "fuzz_targets/host_call.rs"
3232
test = false
3333
doc = false

fuzz/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ You can run the fuzzers with:
66
```sh
77
just fuzz <fuzz_target>
88
```
9-
which evaluates to the following command `cargo +nightly fuzz run host_print --release`. We use the release profile to make sure the release-optimized guest is used. The default fuzz profile which is release+debugsymbols would cause our debug guests to be loaded, since we currently determine which test guest to load based on whether debug symbols are present.
9+
which evaluates to the following command `cargo +nightly fuzz run fuzz_host_print --release`. We use the release profile to make sure the release-optimized guest is used. The default fuzz profile which is release+debugsymbols would cause our debug guests to be loaded, since we currently determine which test guest to load based on whether debug symbols are present.
1010

1111
As per Microsoft's Offensive Research & Security Engineering (MORSE) team, all host exposed functions that receive or interact with guest data must be continuously fuzzed for, at least, 500 million fuzz test cases without any crashes. Because `cargo-fuzz` doesn't support setting a maximum number of iterations; instead, we use the `--max_total_time` flag to set a maximum time to run the fuzzer. We have a GitHub action (acting like a CRON job) that runs the fuzzers for 24 hours every week.
1212

fuzz/fuzz_targets/guest_call.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,17 @@ use hyperlight_host::sandbox::uninitialized::GuestBinary;
2323
use hyperlight_host::sandbox_state::sandbox::EvolvableSandbox;
2424
use hyperlight_host::sandbox_state::transition::Noop;
2525
use hyperlight_host::{MultiUseSandbox, UninitializedSandbox};
26-
use hyperlight_testing::simple_guest_as_string;
26+
use hyperlight_testing::simple_guest_for_fuzzing_as_string;
2727
use libfuzzer_sys::fuzz_target;
2828
static SANDBOX: OnceLock<Mutex<MultiUseSandbox>> = OnceLock::new();
2929

3030
// This fuzz target tests all combinations of ReturnType and Parameters for `call_guest_function_by_name`.
3131
// For fuzzing efficiency, we create one Sandbox and reuse it for all fuzzing iterations.
3232
fuzz_target!(
3333
init: {
34+
3435
let u_sbox = UninitializedSandbox::new(
35-
GuestBinary::FilePath(simple_guest_as_string().expect("Guest Binary Missing")),
36+
GuestBinary::FilePath(simple_guest_for_fuzzing_as_string().expect("Guest Binary Missing")),
3637
None,
3738
None,
3839
None,

fuzz/fuzz_targets/host_call.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use hyperlight_host::sandbox::SandboxConfiguration;
2424
use hyperlight_host::sandbox_state::sandbox::EvolvableSandbox;
2525
use hyperlight_host::sandbox_state::transition::Noop;
2626
use hyperlight_host::{HyperlightError, MultiUseSandbox, UninitializedSandbox};
27-
use hyperlight_testing::simple_guest_as_string;
27+
use hyperlight_testing::simple_guest_for_fuzzing_as_string;
2828
use libfuzzer_sys::fuzz_target;
2929
static SANDBOX: OnceLock<Mutex<MultiUseSandbox>> = OnceLock::new();
3030

@@ -33,7 +33,7 @@ static SANDBOX: OnceLock<Mutex<MultiUseSandbox>> = OnceLock::new();
3333
fuzz_target!(
3434
init: {
3535
let u_sbox = UninitializedSandbox::new(
36-
GuestBinary::FilePath(simple_guest_as_string().expect("Guest Binary Missing")),
36+
GuestBinary::FilePath(simple_guest_for_fuzzing_as_string().expect("Guest Binary Missing")),
3737
None,
3838
None,
3939
None,

fuzz/fuzz_targets/host_print.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use hyperlight_host::sandbox::uninitialized::GuestBinary;
77
use hyperlight_host::sandbox_state::sandbox::EvolvableSandbox;
88
use hyperlight_host::sandbox_state::transition::Noop;
99
use hyperlight_host::{MultiUseSandbox, UninitializedSandbox};
10-
use hyperlight_testing::simple_guest_as_string;
10+
use hyperlight_testing::simple_guest_for_fuzzing_as_string;
1111
use libfuzzer_sys::{fuzz_target, Corpus};
1212

1313
static SANDBOX: OnceLock<Mutex<MultiUseSandbox>> = OnceLock::new();
@@ -19,7 +19,7 @@ static SANDBOX: OnceLock<Mutex<MultiUseSandbox>> = OnceLock::new();
1919
fuzz_target!(
2020
init: {
2121
let u_sbox = UninitializedSandbox::new(
22-
GuestBinary::FilePath(simple_guest_as_string().expect("Guest Binary Missing")),
22+
GuestBinary::FilePath(simple_guest_for_fuzzing_as_string().expect("Guest Binary Missing")),
2323
None,
2424
None,
2525
None,

src/hyperlight_testing/src/lib.rs

+24
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ limitations under the License.
1616

1717
// This crate contains testing utilities which need to be shared across multiple
1818
// crates in this project.
19+
use std::env;
1920
use std::path::PathBuf;
2021

2122
use anyhow::{anyhow, Result};
@@ -129,3 +130,26 @@ pub fn c_callback_guest_as_string() -> Result<String> {
129130
.map(|s| s.to_string())
130131
.ok_or_else(|| anyhow!("couldn't convert callback guest PathBuf to string"))
131132
}
133+
134+
/// Get a fully qualified path to a simple guest binary preferring a binary
135+
/// in the same directory as the parent executable. This will be used in
136+
/// fuzzing scenarios where pre-built binaries will be built and submitted to
137+
/// a fuzzing framework.
138+
pub fn simple_guest_for_fuzzing_as_string() -> Result<String> {
139+
let exe_dir = env::current_exe()
140+
.ok()
141+
.and_then(|path| path.parent().map(|p| p.to_path_buf()));
142+
143+
if let Some(exe_dir) = exe_dir {
144+
let guest_path = exe_dir.join("simpleguest");
145+
146+
if guest_path.exists() {
147+
return Ok(guest_path
148+
.to_str()
149+
.ok_or(anyhow!("Invalid path string"))?
150+
.to_string());
151+
}
152+
}
153+
154+
simple_guest_as_string()
155+
}

0 commit comments

Comments
 (0)