cassemblygcclinker

Verifying no footprint on production code when optionally adding fault injection


I have the following task: Given source code A, modify it into source code B such that it can optionally enable fault injection. When the fault injection is disabled, it shall output the exact same binary as source code A. When fault injection is enabled, it can of course output some other binary. We want the exact same binary when fault injection is disabled to be certain it does not affect the production code. An example in code follows:

Source code A:

if (!allowedEntry) {
    printf("error: Cannot enter\n");
    return FAIL;
}

Source code B: (my changes)

#if defined(ENABLE_FAULT_INJECTION)
    #define IMPORT_FAULT_INJECTION(name) extern bool name
#else
    #define IMPORT_FAULT_INJECTION(name) bool name = false
#endif

// Fault injection variable is set/unset from external library
IMPORT_FAULT_INJECTION(injectNoAllowedEntry);
if (!allowedEntry || injectNoAllowedEntry) {
    printf("error: Cannot enter\n");
    return FAIL;
}

With optimization, the compiler will easily optimize source code A and B to produce similar outputs when ENABLE_FAULT_INJECTION is undefined. I have a script that verifies it by inspecting the resulting assembly output.

However, the problem: The resulting .bin file produced is different. I have at least seen that the compile-time is embedded into the resulting .bin file, which is a difference that does not stem from source code. My two questions are:

  1. Is there any way to disable the embedding of the compile-time into the .bin file? Or any way to override it with my own time? (I realize I could mitigate this issue by compiling the binaries at the same time, but that seems like a brittle solution to me.)

  2. Are there any other subtle differences I need to be aware of that do not stem from source code? And any ways to mitigate these?


Solution

  • I found the problem was with within the project code itself. (I'm not the maintainer of the code base, and it is quite large.)

    One of the differences was a git commit hash that was integrated into the binary. When I was verifying that the binaries were equal, I was compiling the code on different commits. Therefore the git commit has was different.

    The other difference was the timestamp. This was embedded in the binary because a third-party library was using the `__TIME__` macro.

    So if others run into the same issue, looking into similar things might be the solution :)