| name | security-review |
| description | Security review for Rust systems code. Covers memory safety, buffer handling, unsafe code, input validation, resource exhaustion, and supply chain security. |
Security Review (Rust Systems Code)
Examples use placeholder error variants (SomeError::OutOfBounds,
::InvalidOffset, etc.) to illustrate patterns. The actual error type
hierarchy is LibmagicError / ParseError / EvaluationError in
src/error.rs -- check the source for the real variants. AGENTS.md and
GOTCHAS.md are authoritative for project-specific policy.
When to Activate
- Adding new buffer access or offset resolution code
- Handling untrusted input (magic files, target files)
- Adding or reviewing dependencies
- Modifying parser or evaluator logic
- Before releases or PRs with security-sensitive changes
Security Checklist
1. Memory Safety
Bounds-Checked Buffer Access
let byte = buffer[offset];
let byte = *buffer.get(offset).ok_or(EvaluationError::out_of_bounds(offset))?;
let slice = buffer.get(start..end).ok_or(EvaluationError::out_of_bounds(start))?;
Safe String Operations
let rest = &input[2..];
let rest = input.strip_prefix("0x").unwrap_or(input);
Verification Steps
2. Unsafe Code Policy
Deny With One Vetted Exception
unsafe_code = "deny" is configured as a workspace lint in
Cargo.toml [workspace.lints] and inherited by the package via
[lints] workspace = true (verify BOTH are present -- without the
inheritance line the entire lint table is inert). lib.rs additionally
carries #![deny(unsafe_code)]. Exactly one #[allow(unsafe_code)]
exception is sanctioned: the memmap2 map() call in
src/io/mod.rs::create_memory_mapping, which must keep its SAFETY
comment (GOTCHAS S8.2). Any other unsafe block is a finding.
Verification Steps
3. Integer Safety
Overflow Protection
let offset = base + adjustment;
let offset = base.checked_add(adjustment)
.ok_or_else(|| EvaluationError::invalid_offset(format!("{base} + {adjustment}")))?;
let score = base_score.saturating_add(bonus);
Verification Steps
4. Input Validation (Magic Files)
Parser Robustness
Verification Steps
5. Input Validation (Target Files)
File Buffer Safety
use libmagic_rs::io::FileBuffer;
use std::path::Path;
let fb = FileBuffer::new(Path::new(path))?;
let data = fb.as_bytes().get(offset..offset + length);
Verification Steps
6. Resource Exhaustion Prevention
CPU Limits
use libmagic_rs::EvaluationConfig;
let config = EvaluationConfig::performance()
.with_stop_at_first_match(true);
let config = EvaluationConfig::default()
.with_timeout_ms(Some(1000))
.with_max_recursion_depth(50);
Actual fields on EvaluationConfig (per src/config.rs): timeout_ms: Option<u64> (milliseconds, clamped to MAX_SAFE_TIMEOUT_MS = 5 minutes),
max_recursion_depth: u32, stop_at_first_match: bool. The type is
#[non_exhaustive] -- check the source for the current full field set.
Verification Steps
7. Supply Chain Security
Dependency Audit
mise exec -- cargo audit
mise exec -- cargo deny check
mise exec -- cargo tree --depth 2
Verification Steps
8. Error Information Leakage
Safe Error Messages
return Err(format!("Failed to read {full_path}: {system_error}").into());
return Err(ParseError::IoError(format!("magic file not found: {name}")));
Verification Steps
9. CLI Argument Safety
Path Handling
#[derive(Parser)]
struct Args {
file: PathBuf,
#[arg(long)]
magic_file: Option<PathBuf>,
}
Verification Steps
Pre-Release Security Checklist
References