Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rmm: Initial fuzzing setup #418

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ members = [
"plat/fvp",
"realm/rsi-test",
"rmm/",
"rmm/fuzz/",
"sdk",
]

Expand All @@ -19,3 +20,7 @@ panic = "abort"
[profile.release]
lto = true
panic = "abort"

[profile.fuzz]
inherits = "dev"
panic = "unwind"
2 changes: 1 addition & 1 deletion rmm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ mc_rmi_rec_destroy = []
mc_rmi_version = []

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(kani)'] }
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(kani)', 'cfg(fuzzing)'] }
5 changes: 5 additions & 0 deletions rmm/fuzz/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[build]
target = "aarch64-unknown-linux-gnu"

[target.aarch64-unknown-linux-gnu]
linker = "../../assets/toolchain/aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc"
26 changes: 26 additions & 0 deletions rmm/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "rmm_fuzz"
version = "0.0.0"
publish = false
edition = "2021"

[package.metadata]
cargo-fuzz = true

[dependencies]
libfuzzer-sys = { version = "0.4.0", features = ["arbitrary-derive"] }
islet_rmm = { path = "../" }

[[bin]]
name = "rmi_version_fuzz"
path = "fuzz_targets/rmi_version_fuzz.rs"
test = false
doc = false
bench = false

[[bin]]
name = "rmi_features_fuzz"
path = "fuzz_targets/rmi_features_fuzz.rs"
test = false
doc = false
bench = false
11 changes: 11 additions & 0 deletions rmm/fuzz/fuzz_targets/rmi_features_fuzz.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![no_main]

use islet_rmm::rmi::{FEATURES};
use islet_rmm::test_utils::*;

use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: u64| {
let feature_reg_index = data as usize;
let _ret = rmi::<FEATURES>(&[feature_reg_index]);
});
11 changes: 11 additions & 0 deletions rmm/fuzz/fuzz_targets/rmi_version_fuzz.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![no_main]

use islet_rmm::rmi::{VERSION};
use islet_rmm::test_utils::*;

use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: u64| {
let req = data as usize;
let _ret = rmi::<VERSION>(&[req]);
});
6 changes: 3 additions & 3 deletions rmm/src/asm.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::arch::asm;

pub const SMC_SUCCESS: usize = 0;
#[cfg(any(kani, miri, test))]
#[cfg(any(kani, miri, test, fuzzing))]
pub const SMC_ERROR: usize = 1;

pub fn smc(cmd: usize, args: &[usize]) -> [usize; 8] {
Expand All @@ -22,7 +22,7 @@ pub fn smc(cmd: usize, args: &[usize]) -> [usize; 8] {
};
put(&mut ret);
put(&mut padded_args);
#[cfg(any(kani, miri, test))]
#[cfg(any(kani, miri, test, fuzzing))]
if cmd == crate::rmi::gpt::MARK_REALM {
use crate::get_granule;
use crate::granule::entry::GranuleGpt;
Expand Down Expand Up @@ -50,7 +50,7 @@ pub fn smc(cmd: usize, args: &[usize]) -> [usize; 8] {
}

// TODO: support more number of registers than 8 if needed
#[cfg(not(any(kani, miri, test)))]
#[cfg(not(any(kani, miri, test, fuzzing)))]
unsafe {
asm!(
"smc #0x0",
Expand Down
2 changes: 1 addition & 1 deletion rmm/src/exception/trap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ pub extern "C" fn handle_lower_exception(
rec.context.simd.is_used = true;
unsafe {
if rec.context.simd.is_saved {
#[cfg(not(any(miri, test)))]
#[cfg(not(any(miri, test, fuzzing)))]
match Syndrome::from(esr) {
Syndrome::FPU => simd::restore_fpu(&rec.context.simd.fpu),
Syndrome::SVE | Syndrome::SME => {
Expand Down
32 changes: 16 additions & 16 deletions rmm/src/granule/array/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ use safe_abstraction::raw_ptr;
use spinning_top::{Spinlock, SpinlockGuard};
use vmsa::guard::Content;

#[cfg(not(any(kani, miri, test)))]
#[cfg(not(any(kani, miri, test, fuzzing)))]
use crate::granule::{FVP_DRAM0_REGION, FVP_DRAM1_IDX, FVP_DRAM1_REGION};

// Safety: concurrency safety
// - For a granule status table that manages granules, it doesn't use a big lock for efficiency.
// So, we need to associate "lock" with each granule entry.

#[cfg(not(any(kani, miri, test)))]
#[cfg(not(any(kani, miri, test, fuzzing)))]
#[derive(Debug)]
pub struct Granule {
/// granule state
state: u8,
/// granule ref count
ref_count: AtomicU8,
}
#[cfg(any(kani, miri, test))]
#[cfg(any(kani, miri, test, fuzzing))]
// DIFF: `gpt` ghost field is added to track GPT entry's status
pub struct Granule {
/// granule state
Expand All @@ -41,7 +41,7 @@ pub enum GranuleGpt {
GPT_REALM,
}

#[cfg(any(miri, test))]
#[cfg(any(miri, test, fuzzing))]
#[derive(Copy, Clone, PartialEq)]
pub enum GranuleGpt {
GPT_NS,
Expand All @@ -50,13 +50,13 @@ pub enum GranuleGpt {
}

impl Granule {
#[cfg(not(any(kani, miri, test)))]
#[cfg(not(any(kani, miri, test, fuzzing)))]
fn new() -> Self {
let state = GranuleState::Undelegated;
let ref_count = AtomicU8::new(0);
Granule { state, ref_count }
}
#[cfg(any(kani, miri, test))]
#[cfg(any(kani, miri, test, fuzzing))]
// DIFF: `state` and `gpt` are filled with non-deterministic values
fn new() -> Self {
#[cfg(kani)]
Expand All @@ -80,7 +80,7 @@ impl Granule {
}
}

#[cfg(any(miri, test))]
#[cfg(any(miri, test, fuzzing))]
{
Self {
state: GranuleState::Undelegated,
Expand All @@ -106,12 +106,12 @@ impl Granule {
self.ref_count.load(Ordering::SeqCst) as usize
}

#[cfg(any(kani, miri, test))]
#[cfg(any(kani, miri, test, fuzzing))]
pub fn set_gpt(&mut self, gpt: GranuleGpt) {
self.gpt = gpt;
}

#[cfg(any(kani, miri, test))]
#[cfg(any(kani, miri, test, fuzzing))]
pub fn is_valid(&self) -> bool {
self.state >= GranuleState::Undelegated &&
self.state <= GranuleState::RTT &&
Expand Down Expand Up @@ -176,22 +176,22 @@ impl Granule {
(entry_addr - table_base) / core::mem::size_of::<Entry>()
}

#[cfg(not(any(kani, miri, test)))]
#[cfg(not(any(kani, miri, test, fuzzing)))]
fn index_to_addr(&self) -> usize {
let idx = self.index();
if idx < FVP_DRAM1_IDX {
return FVP_DRAM0_REGION.start + (idx * GRANULE_SIZE);
}
FVP_DRAM1_REGION.start + ((idx - FVP_DRAM1_IDX) * GRANULE_SIZE)
}
#[cfg(any(kani, miri, test))]
#[cfg(any(kani, miri, test, fuzzing))]
// DIFF: calculate addr using GRANULE_REGION
pub fn index_to_addr(&self) -> usize {
use crate::granule::{GRANULE_REGION, GRANULE_STATUS_TABLE_SIZE};
let idx = self.index();
assert!(idx < GRANULE_STATUS_TABLE_SIZE);

#[cfg(any(miri, test))]
#[cfg(any(miri, test, fuzzing))]
return crate::test_utils::align_up(unsafe {
GRANULE_REGION.as_ptr() as usize + (idx * GRANULE_SIZE)
});
Expand All @@ -200,7 +200,7 @@ impl Granule {
return unsafe { GRANULE_REGION.as_ptr() as usize + (idx * GRANULE_SIZE) };
}

#[cfg(not(any(kani, miri, test)))]
#[cfg(not(any(kani, miri, test, fuzzing)))]
fn zeroize(&mut self) {
let addr = self.index_to_addr();

Expand All @@ -211,7 +211,7 @@ impl Granule {
core::ptr::write_bytes(addr as *mut u8, 0x0, GRANULE_SIZE);
}
}
#[cfg(any(kani, miri, test))]
#[cfg(any(kani, miri, test, fuzzing))]
// DIFF: assertion is added to reduce the proof burden
// `write_bytes()` uses a small count value
fn zeroize(&mut self) {
Expand All @@ -229,11 +229,11 @@ impl Granule {

pub struct Entry(Spinlock<Granule>);
impl Entry {
#[cfg(not(any(kani, miri, test)))]
#[cfg(not(any(kani, miri, test, fuzzing)))]
pub fn new() -> Self {
Self(Spinlock::new(Granule::new()))
}
#[cfg(any(kani, miri, test))]
#[cfg(any(kani, miri, test, fuzzing))]
// DIFF: assertion is added to reduce the proof burden
pub fn new() -> Self {
let granule = Granule::new();
Expand Down
Loading
Loading