EFInject
Software-implemented fault injection (SWIFI) is an established method to emulate hardware faults in computer systems. Existing approaches either extend the operating system by special drivers, modify the runtime environment, or change the application under test.
In cooperation with Fujitsu Technology Solutions in Paderborn, we worked on the realization of a novel fault injection concept based on EFI firmware technology. Our approach extends the firmware of these systems in order to a) make fault injection completely transparent to the operating system, and to b) support a larger variety of fault types. No modifications to the operating system or the application code are needed.
Due to technical limitations of the EFI implementations available today, the project has been suspended. Our final software stack is freely available for further research.
Download
You can download compiled packages here. Be aware that the architecture must match your (U)EFI firmware architecture.
Installation
Extract the following files from the binary distribution into a folder on the EFI system partition:
InjectReportApp.efi
InjectReportDxe.efi
loadefinject.nsh
Depending on the operating system you need the following files accessible from within the operating system:
- Windows:
tick.cmd
andefiwin.exe
- Linux:
tick.sh
Injection cycles
EFInject is prepared to perform injections several times. The package provides a helper script and application to run a specified number of injection cycles.
First of all you need to configure the injection itself. The configuration method is described in a separate section below. After configuring the driver you can set the number of injection cycles using the helper application:
InjectReportApp setcycles [count]
To integrate with EFInject with your system you have to modify both the
loadefinject.nsh
and your startup.nsh
. In loadefinject.nsh
replace
the exit
command with whatever is necessary to boot the operating system
under test. Then modify your startup.nsh
so that you change the directory
to the one where the EFInject file live and that loadefinject.nsh
is called
afterwards. Finally make sure that the default boot option is the internal EFI
shell which calls the startup.nsh
script.
Modify the operating so that it starts the appropriate tick script with root/Administrator privileges during boot.
Configuration
To configure EFInject, launch the EFInject helper application from the EFI Shell in the following way:
InjectReportApp configure [configuration string]
The configuration string consists of four parameters delimited by semicolons:
the trigger mechanism, currently
oneshot
orinterval
the trigger parameters, which is the number of ticks until the first or between the injections, depending on the selected trigger
the injection mechanism, currently
reset
,memory
orregister
1the injection parameter
for the reset injector: the parameter is ignored
for the memory injector: three hexadecimal values separated by commas: the virtual memory address for the injection, an OR- and an XOR-parameter; the injection semantic is
*memoryLocation = (*memoryLocation | orParameter) ^ xorParameter
for the register injector: three values, also using hexadecimal numbers: the uppercase name of a general purpose register, and the OR- and XOR-parameter already described for the memory injector
Both injectors always work with native-sized memory words, i.e. with DWORDs on IA32 and with QWORDs on X64.
The OR-XOR-semantics allow for four different actions for each bit in the register/memory location:
- or=0, xor=0: no action
- or=0, xor=1: flip bit
- or=1, xor=0: set to 1
- or=1, xor=1: set to 0
At this time the supported registers are:
- for IA32: EFLAGS 2, EDI, ESI, EBP, EBX, EDX, ECX, EAX
- for X64: RFLAGS 3, RAX, RBX, RCX, RDX, RDI, RSI, R8, R9, R10, R11, R12, R13, R14, R15, RBP
- 1.
- ^ There is a third injection method called
nop
which does nothing and ignores its configuration parameter but can be used to test the infrastructure. No crashes should occur when using thenop
injector. - 2.
- ^ Not all flags of EFLAGS are supported: VM, RF, VIP and VIF are ignored.
- 3.
- ^ The EFLAGS restrictions apply and the upper 32 bit of RFLAGS are ignored.
Configuration Examples
interval;3;register;EAX,00000000,0000000F
- flips the lower four bits of the general-purpose EAX register on every third tick (IA32)
oneshot;4;register;RAX,1,0
- sets the least-significant bit of RAX
interval;3;memory;F0,0,1
- flips the least-significant bit of the memory cell at 0x000000f0
Troubleshooting
If something does not work, try the following steps:
The configuration oneshot;1;nop;
should always be valid regardless of the
underlying platform. Therefore the following commands should always work and
result in a running driver:
InjectReportApp.efi configure oneshot;1;nop; load InjectReportDxe.efi
To test the driver itself, you can issue commands from the EFI shell. As the
driver uses the variable interface to communicate with the shell and operating
systems, you can use the dmpstore
tool to run some tests. The following
command should print some data showing a UTF16-encoded Callback works!
string:
dmpstore Test
If you run Linux as an operating system after loading the driver, the equivalent to the command above would be: (run as root)
hd /sys/firmware/efi/vars/Test-8b1cd116-7f14-4594-8474-edbebda318ce/data
In the commands above, you can replace the verb Test
with Inject
to
perform an immediate injection (independent of any trigger) or Tick
to
call the trigger once.