Skip to content
Merged
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
2 changes: 1 addition & 1 deletion artifacts/cybersecurity/goals-and-requirements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,7 @@ artifacts:
- id: CV-15
type: cybersecurity-verification
title: ELF and MCUboot fuzz testing
status: draft
status: approved
description: >
Fuzz targets for ELF and MCUboot parsers to discover edge cases
in header parsing, section validation, and resource bounds
Expand Down
21 changes: 21 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,24 @@ path = "fuzz_targets/fuzz_rekor_entry.rs"
test = false
doc = false
bench = false

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

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

[[bin]]
name = "fuzz_format_detection"
path = "fuzz_targets/fuzz_format_detection.rs"
test = false
doc = false
bench = false
55 changes: 55 additions & 0 deletions fuzz/fuzz_targets/fuzz_elf_parsing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//! Fuzz target for ELF binary parsing
//!
//! Tests the ELF artifact parser which handles:
//! - ELF header validation (magic bytes, class, endianness)
//! - Section header table parsing and consistency checks (SC-12)
//! - Section overlap detection (UCA-13)
//! - Resource bounds enforcement (UCA-17: 256MB max, 4096 max sections)
//! - .sigil section discovery
//! - Full-file hash computation (AS-14)
//!
//! Security concerns:
//! - Malformed section headers with overlapping ranges
//! - Integer overflows in offset/size calculations
//! - Excessive section counts triggering memory exhaustion
//! - Inconsistent 32-bit vs 64-bit header fields
//! - Circular or out-of-bounds string table references
//! - Polyglot files with both WASM and ELF magic (AS-17)

#![no_main]

use libfuzzer_sys::fuzz_target;
use wsc::format::elf::ElfArtifact;
use wsc::format::{FormatType, SignableArtifact, validate_format_consistency};

fuzz_target!(|data: &[u8]| {
// Test ELF parsing with all validation checks
if let Ok(artifact) = ElfArtifact::from_bytes(data.to_vec()) {
// Exercise hash computation (must not panic)
let _ = artifact.compute_hash();

// Exercise format type
assert_eq!(artifact.format_type(), FormatType::Elf);

// Exercise content bytes access
let _ = artifact.content_bytes();

// Exercise signature detachment
let _ = artifact.detach_signature();

// Exercise serialization
let mut output = Vec::new();
let _ = artifact.serialize(&mut output);
}

// Test format detection on the input
let _ = FormatType::detect(data);

// Test format consistency validation
// This should catch polyglot files (AS-17)
if data.len() >= 4 {
let _ = validate_format_consistency(FormatType::Elf, data);
let _ = validate_format_consistency(FormatType::Wasm, data);
let _ = validate_format_consistency(FormatType::Mcuboot, data);
}
});
49 changes: 49 additions & 0 deletions fuzz/fuzz_targets/fuzz_format_detection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//! Fuzz target for format detection and polyglot validation
//!
//! Tests the format detection logic which handles:
//! - Magic byte detection for WASM, ELF, MCUboot
//! - Format consistency validation (SC-15)
//! - Polyglot file rejection (AS-17)
//!
//! Security concerns:
//! - Files that are valid as multiple formats simultaneously
//! - Files with misleading magic bytes followed by different content
//! - Very short inputs that partially match magic bytes
//! - Inputs that trigger different detection results depending on length

#![no_main]

use libfuzzer_sys::fuzz_target;
use wsc::format::{FormatType, validate_format_consistency};

fuzz_target!(|data: &[u8]| {
// Detect format from magic bytes
let detected = FormatType::detect(data);

// If a format was detected, consistency check against each format type
// should pass for the detected format and fail for others
if let Some(fmt) = detected {
// Should pass for detected format
assert!(validate_format_consistency(fmt, data).is_ok());

// Should fail for other formats (polyglot detection)
let other_formats = [FormatType::Wasm, FormatType::Elf, FormatType::Mcuboot];
for other in &other_formats {
if *other != fmt {
// Other formats should either fail or not detect
let _ = validate_format_consistency(*other, data);
}
}
}

// Test all format string parsing
for name in &["wasm", "elf", "mcuboot", "WASM", "ELF", "MCUBOOT", "unknown", ""] {
let _ = FormatType::from_str(name);
}

// Test content type IDs and domain strings are consistent
for fmt in &[FormatType::Wasm, FormatType::Elf, FormatType::Mcuboot] {
let _id = fmt.content_type_id();
let _domain = fmt.signature_domain();
}
});
55 changes: 55 additions & 0 deletions fuzz/fuzz_targets/fuzz_mcuboot_parsing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//! Fuzz target for MCUboot firmware image parsing
//!
//! Tests the MCUboot artifact parser which handles:
//! - MCUboot magic byte validation
//! - Image header parsing (ih_img_size, ih_hdr_size)
//! - Independent image size verification (SC-13)
//! - Header size vs file content consistency (UCA-14, AS-15)
//! - Resource bounds enforcement (16MB max)
//! - Payload extraction
//! - TLV trailer signature embedding
//!
//! Security concerns:
//! - Header ih_img_size declares smaller size than actual content,
//! causing partial-image signature (AS-15)
//! - Integer overflows in header_size + image_size calculation
//! - Truncated input with valid magic but incomplete header
//! - Maximum size enforcement bypass
//! - TLV serialization with signature attachment

#![no_main]

use libfuzzer_sys::fuzz_target;
use wsc::format::mcuboot::McubootArtifact;
use wsc::format::{FormatType, SignableArtifact};

fuzz_target!(|data: &[u8]| {
// Test MCUboot parsing with all validation checks
if let Ok(mut artifact) = McubootArtifact::from_bytes(data.to_vec()) {
// Exercise hash computation (must not panic)
let _ = artifact.compute_hash();

// Exercise format type
assert_eq!(artifact.format_type(), FormatType::Mcuboot);

// Exercise content bytes (payload extraction)
let payload_len = artifact.content_bytes().len();
// Payload must not be empty if parsing succeeded
assert!(payload_len > 0);

// Exercise signature attachment and serialization roundtrip
let fake_sig = vec![0xAA; 64]; // Ed25519 signature size
if artifact.attach_signature(&fake_sig).is_ok() {
let mut output = Vec::new();
let _ = artifact.serialize(&mut output);

// Output should be larger than payload (TLV trailer added)
if !output.is_empty() {
assert!(output.len() >= payload_len);
}
}

// Exercise signature detachment
let _ = artifact.detach_signature();
}
});
Loading