swage_core/
victim.rs

1//! Victim orchestration for Rowhammer attacks.
2//!
3//! This module provides the infrastructure for managing victim applications or memory
4//! regions that are targeted by Rowhammer attacks. A victim can be:
5//! - A memory region checked for bit flips ([`MemCheck`](crate::MemCheck))
6//! - A process or application being attacked
7//! - Other custom victim implementations
8//!
9//! The [`VictimOrchestrator`] trait defines the lifecycle and interface for all victims.
10
11use crate::memory::BitFlip;
12use crate::memory::FlippyPage;
13use crate::memory::LinuxPageMapError;
14use core::panic;
15use serde::Serialize;
16use thiserror::Error;
17
18/// Errors that can occur during victim operations.
19#[derive(Error, Debug)]
20pub enum HammerVictimError {
21    /// No bit flips were detected during the check operation.
22    #[error("No flips detected")]
23    NoFlips,
24    /// An I/O error occurred during victim operations.
25    #[error(transparent)]
26    IoError(#[from] std::io::Error),
27    /// The victim is not currently running.
28    #[error("Victim is not running")]
29    NotRunning,
30    /// Failed to construct the victim with the given configuration.
31    #[error("Failed to construct victim: {0}")]
32    ConstructionError(Box<dyn std::error::Error>),
33    /// The expected flippy page was not found.
34    #[error("Flippy page not found")]
35    FlippyPageNotFound,
36    /// The flippy page offset does not match the expected value.
37    #[error("Flippy page offset mismatch: expected {expected}, actual {actual:?}")]
38    FlippyPageOffsetMismatch {
39        /// Expected page offset
40        expected: usize,
41        /// Actual flippy page information
42        actual: FlippyPage,
43    },
44    /// An error occurred while accessing Linux pagemap.
45    #[error(transparent)]
46    LinuxPageMapError(#[from] LinuxPageMapError),
47    /// A protocol-level error occurred in victim communication.
48    #[error("Protocol Error: {0}")]
49    ProtocolError(String),
50}
51
52/// Result type returned by victim check operations.
53///
54/// This enum represents the different types of results that can be returned
55/// when checking if a Rowhammer attack was successful.
56#[derive(Debug, Serialize)]
57pub enum VictimResult {
58    /// One or more bit flips were detected at specific memory locations.
59    BitFlips(Vec<BitFlip>),
60    /// A string result describing the attack outcome.
61    String(String),
62    /// Multiple string results describing attack outcome.
63    Strings(Vec<String>),
64    /// No meaningful result to report.
65    Nothing,
66}
67
68impl VictimResult {
69    /// Extracts the bit flips from this result.
70    ///
71    /// # Panics
72    ///
73    /// Panics if this result is not the `BitFlips` variant.
74    pub fn bit_flips(self) -> Vec<BitFlip> {
75        match self {
76            VictimResult::BitFlips(flips) => flips,
77            _ => panic!("Invalid variant. Expected BitFlips, got {:?}", self),
78        }
79    }
80}
81
82/// Trait for orchestrating victim applications or memory regions targeted by Rowhammer attacks.
83///
84/// Implementors of this trait define how to initialize, monitor, and check victim
85/// memory regions or processes for the effects of Rowhammer attacks (e.g., bit flips).
86/// The trait provides a lifecycle for victim management: start, initialize, check, and stop.
87///
88/// # Lifecycle
89///
90/// The typical victim lifecycle is:
91/// 1. [`start()`](VictimOrchestrator::start) - Initialize victim resources (called once)
92/// 2. [`init()`](VictimOrchestrator::init) - Prepare victim state before hammering
93/// 3. Hammering occurs (external to victim)
94/// 4. [`check()`](VictimOrchestrator::check) - Verify if attack succeeded
95/// 5. [`stop()`](VictimOrchestrator::stop) - Clean up victim resources
96///
97/// Steps 2-4 may be repeated multiple times between start and stop.
98///
99/// # Examples
100///
101/// See `swage-victim-dev-memcheck` or the [`MemCheck`](crate::MemCheck) implementation
102/// for concrete usage examples.
103pub trait VictimOrchestrator {
104    /// Starts the victim and allocates required resources.
105    ///
106    /// This method is called once at the beginning of an experiment to set up
107    /// the victim environment. It may involve starting processes, mapping memory,
108    /// or establishing communication channels.
109    ///
110    /// # Errors
111    ///
112    /// Returns [`HammerVictimError`] if initialization fails.
113    fn start(&mut self) -> Result<(), HammerVictimError>;
114
115    /// Initializes the victim state before a hammering round.
116    ///
117    /// This method is called before each hammering operation to prepare the
118    /// victim memory or process to a known state. For memory-based victims,
119    /// this typically involves writing specific patterns to memory.
120    /// For process-based victims, this might involve triggering an operation
121    /// or sending a signal to the victim process.
122    fn init(&mut self);
123
124    /// Checks if the hammering attack was successful.
125    ///
126    /// This method examines the victim to detect any effects of the Rowhammer
127    /// attack, typically by checking for bit flips in memory or unexpected
128    /// behavior in victim processes.
129    ///
130    /// # Returns
131    ///
132    /// Returns `Ok(VictimResult)` with attack results if effects are detected,
133    /// or [`HammerVictimError::NoFlips`] if no effects are found.
134    ///
135    /// # Errors
136    ///
137    /// Returns an error if:
138    /// * No bit flips or effects are detected ([`HammerVictimError::NoFlips`])
139    /// * I/O operations fail
140    /// * The victim is not in a valid state
141    fn check(&mut self) -> Result<VictimResult, HammerVictimError>;
142
143    /// Stops the victim and releases resources.
144    ///
145    /// This method is called at the end of an experiment to clean up the victim
146    /// environment, stop processes, and release any allocated resources.
147    fn stop(&mut self);
148
149    /// Optionally serializes victim-specific data to JSON.
150    ///
151    /// This method allows victims to provide additional metadata or state
152    /// information that can be included in experiment results.
153    ///
154    /// # Returns
155    ///
156    /// Returns `Some(Value)` with serialized data, or `None` if no additional
157    /// data is available.
158    fn serialize(&self) -> Option<serde_json::Value> {
159        None
160    }
161}