WIP: background section

This commit is contained in:
2026-07-05 23:45:52 +02:00
parent af400ab8d4
commit 3ba5be8c86
7 changed files with 3984 additions and 12 deletions
+43 -9
View File
@@ -6,17 +6,51 @@
\section{Fault-Injection Leveraged}\label{sec:fail}
\begin{itemize}
\item FAIL*~\autocite{schirmeierFAILOpenVersatile2015} architecture
\item FailBochs backend, how does FAIL* inject
\item FAIL*'s generic-experiment
\item How to perform a FAIL* experiment
\end{itemize}
\Gls{fail}~\autocite{schirmeierFAILOpenVersatile2015} is an emulation-based vulnerability analysis tool.
It provides a toolset to perform \gls{fi} experiments to analyze the vulnerability of software to transient hardware faults.
In contrast to other \gls{fi} tools, \Gls{fail} enables deep simulator state access while simultaneously supporting multiple simulator backends, like BOCHS~\autocite{bochs} or gem5\footnote{\url[2026-07-02]{https://www.gem5.org/}}. % TODO: Give examples for other FI frameworks
In contrast to other \gls{fi} tools\todo{give examples}, \Gls{fail} enables deep simulator state access while simultaneously supporting multiple simulator backends, like BOCHS~\autocite{bochs} or gem5\footnote{\url[2026-07-02]{https://www.gem5.org/}}.
% FAIL components/structure/architecture
\Gls{fail} is split into different components: A \textit{campaign} consists of multiple \gls{fi} \textit{experiments}, where each experiment injects a single fault.
The \textit{campaign controller} distributes those experiments to running \Gls{fail} instances.
Campaigns can be parallelized by running multiple instances on different systems or cores.
Each experiment utilizes \Gls{fail}'s \textit{simulator abstraction layer} to control the target backend, to fast-forward the target to the desired state and inject a fault.
This abstraction layer allows switching out backends to support different target platforms.
To perform a vulnerability analysis, the examined program needs to be instrumented with fences that define the region to trace (see \autoref{lst:tracefencemarkers}).
\begin{codeblock}[label=lst:tracefencemarkers]{Trace Region Fence}{.cpp}
\inputminted{cpp}{\subfix{listings/tracefence.cpp}}
\end{codeblock}
\Gls{fail} then records the instruction pointer changes and memory accesses inside this region during the so-called \textquote{golden run}: a faultless execution of the program that determines which injections should be performed during the campaign.
Then, the golden run is enriched with the traced region's disassembly to take into account the read and written registers.
The last step before campaign execution is the \textit{prune} step, where the collected data is translated into corresponding experiments.
Different data points from the trace that result in the same \textquote{fault-similarity class} (as used by Schirmeier~\autocite{schirmeierEfficientFaultInjectionbasedAssessment}) are removed from the campaign.
Two experiments belong to the same similarity class if the \textit{relevant} parts of their resulting simulator state are identical.
From the pruned instruction pointer changes, memory accesses, and register accesses \Gls{fail} constructs a number of \textit{pilots}: representatives of the existing fault-similarity classes.
Each pilot then corresponds to a single experiment.
\Gls{fail}'s campaigns are event-driven: the user specifies conditions, for example an access to a certain memory region.
Once a condition is reached, a user-defined action is performed, like injecting a fault or registering a certain experiment outcome.
Users do not have to write every campaign from scratch, as \Gls{fail} includes a \textquote{generic experiment} which can be used as a starting point.
The generic experiment performs three types of fault injections by default:
\begin{itemize}
\item \sansbf{Memory} injections: Before the program reads from a memory address, a fault is injected.
\item \sansbf{Register} injections: Before the program reads from a register, a fault is injected.
\item \sansbf{Instruction Pointer} injections: The instruction pointer's value is randomized to disturb the program flow and introduce random jumps.
\end{itemize}
Furthermore, different experiment outcomes are classified:
\begin{itemize}
\item \sansbf{Trap}: The injected fault caused the simulated CPU to throw an exception.
\item \sansbf{Timeout}: The injected fault caused the program to stall.
\item \sansbf{Ok Marker} (\code{fail\_marker\_positive()}): The program executed correctly even with the injected fault.
\item \sansbf{Detected Marker} (\code{fail\_marker\_detected()}): The injected fault was detected by the program.
\item \sansbf{Fail Marker} (\code{fail\_marker\_negative()}): The injected fault was not detected by the program.
\item \sansbf{Access Outerspace}: Caught if the program reads or writes anywhere outside valid ELF addresses.
\item \sansbf{Write Textsegment}: Caught if the program writes to addresses inside the \code{.text} section of the program.
\end{itemize}
Ok/Detected/Fail outcomes are classified by instrumenting the tested code with \textquote{markers} (see \autoref{lst:classificationmarkers}).
If the program execution passes a marker, the experiment outcome is classified accordingly.
\begin{codeblock}[label=lst:classificationmarkers]{Classification Markers}{.cpp}
\inputminted{cpp}{\subfix{listings/classificationmarkers.cpp}}
\end{codeblock}
\end{document}
@@ -0,0 +1,6 @@
// Continuation of previous example
if (sum == 100) {
fail_marker_positive();
} else {
fail_marker_negative();
}
@@ -0,0 +1,8 @@
fail_start_trace();
int sum = 0;
for (int i = 0; i < 100; ++i) {
++sum;
}
fail_stop_trace();