I am working on safety critical system and now I am attempting to introduce a software technique for control flow checking. Control Flow Error or CFE which happens due to the transient fault should be addressed at the design phase. Now, I completed the technique which written in c language and for evaluation I need a tool to implement fault injection. My technique should work both for single and multi-threaded programs. The fault injection tool that I need should not change the number of instructions in the target program and the fault model selected is SEU or single error upset (bit-flip). Fault injector routine will just make a bit flip in EIP register or in any general purpose registers.
I have read more and more about SWFI software fault injection tools and let me explain it briefly. SWFI are used time in term of introducing a software interruption (for example signals in Unix-like systems). For example, assume that we have a simple c program. We can install a signal (I prefer using "sigaction" with sa_flags = SA_SIGINFO) and wait for an incoming signal (ualarm(x,0), then the kernel move control to sa_sigaction handler which has 3 arguments. The most important one is the third argument which is void *context (pointer to the machine specific context). Now, we can modify this structure in order to perform data error or control flow error which implemented by playing with gregs[REG_EIP].
ucontext_t *context = (ucontext_t *)contextt;
context->uc_mcontext.gregs[REG_EIP]= an appropriate value ;
see this: (this is not a good code, it is just for testing)
#include
#define __USE_GNU
#include
#include
#include
#include
#include
#include
static void hdl (int sig, siginfo_t *siginfo, void *contextt)
{
printf("signal caught\n");
ucontext_t *context = (ucontext_t *)contextt;
//here, I want to force the processor to jump
//to an appropriate address after finishing
//the hdl (signal handler). For example, assume
//that the signal is raised after finishing the
//instruction (printf("I am still alive 2\n");)
//and before the instruction (printf("I am still alive 3\n");).
//Now, As I understood, the gregs[REG_EIP] should hold the
//address of the instruction (printf("I am still alive 3\n");)
//I want to force the CPU to jump to the last
//instruction (printf("Iam still alive 5\n");)
// I tested very and very cases, but always segmentation
// fault has been occured.
// I think we should jump something like this:
// unsigned long is the length of instruction (as I know)
size_t size = sizeof(unsigned long);
context->uc_mcontext.gregs[REG_EIP] += size;
}
int main (int argc, char *argv[])
{
struct sigaction act;
memset (&act, '\0', sizeof(act));
act.sa_sigaction = &hdl;
act.sa_flags = SA_SIGINFO;
sigaction(SIGALRM, &act, NULL);
ualarm (81, 0);
printf("I am still alive 1\n");
printf("I am still alive 2\n");
printf("I am still alive 3\n");
printf("I am still alive 4\n");
printf("I am still alive 5\n");
return 0;
}
The most confusing question is when we move to signal handler and get the EIP register from context, What does EIP really hold? interrupted instruction address? next instruction that will be executed after finishing signal handler? and how could we perform Control Flow Error and avoiding as possible as segmentation fault?
Thank you for any help. With regards.