Open Maknee opened 1 year ago
Hi @Maknee,
First of all, thanks for reporting this and for the excellent analysis.
This is indeed a false-positive. We have not extensively tested SiliFuzz outside of the platforms mentioned in the README and it's a bummer we didn't catch this earlier.
In terms of workarounds, the most immediate thing you can do is taskset(1)
the entire pipeline (simple_fix_tool
+ ochestrator/runner) such that it runs on just E-/P- cores. Effectively this means producing two sets of corpus files. This is similar to the existing PlatformId except there's no native support for this.
Filtering this out is hard-to-impossible I would say. A naive approach of simply not comparing the EFLAGS
fails if you consider conditional branching and PUSHF
. We can ostensibly utilize the existing single-stepping machinery here but that would require good knowledge of the ISA
I'm not sure if this would affect other 12th gen intel CPUs.
I suspect all of the processors listed here https://en.wikipedia.org/wiki/Alder_Lake#List_of_12th_generation_Alder_Lake_processors are affected if they have both P- and E-cores. I don't have immediate access to any of these to verify.
Thanks @ksteuck for confirming that this case is a false positive.
The first suggestion should work -- producing two different set of corpuses to run on p-cores/e-cores. The second suggestion is definitely more tricky to get right. In some cases, eflag comparisons do matter as you mentioned.
Another idea I was thinking of is a tool that can inject some value (say 0) for values that are undefined.
Say, we're trying to deal with the false positive I mentioned.
This tool can scan for certain instructions (say imul instruction) and inject a sequence of instructions to set the ZF to 0 without affecting other flags after executing the imul instruction.
For example, consider this sequence to zero out the zero flag.
pushfd
and dword ptr [rsp], 0xFFFFFFCF
popfd
Another way to handle this case is to attach a debugger to the runner, set a breakpoint and modify ZF when the instruction is hit and the resume execution afterwards. This will incur much more overhead for fuzzing.
However, the ideas I mentioned require a bit of engineering and manual work to generate sequences for instructions that produce undefined results in certain registers. I think it's simplest and quickest to run different set of corpuses on different set of cores and I'll probably do that.
Hopefully, this type of false positive only occurs on 12th gen processors. I don't have access to other types of processors with p/e cores to check if this false positive case occurs on those processors.
This tool can scan for certain instructions (say imul instruction) and inject a sequence of instructions to set the ZF to 0 without affecting other flags after executing the imul instruction.
Injecting code like this opens an entirely new can of worms unfortunately and introduces an undesirable skew between the corpus generation and corpus execution parts of the pipeline.
As long as the undefined bits are consistent within a single microarch it makes more sense for us to keep the current approach. This means modelling a single Alderlake CPU as two separate CPUs and all the added complexity associated with it.
Hi, silifuzz authors
I recently found many false positives with dealing with eflags on the two 12900 CPUs I'm fuzzing on. I'm not sure if this would affect other 12th gen intel CPUs.
Example shown below:
Bytes:
\xBC\xC4\x04\x8A\xD2\x66\x81\xDE\xF2\x00\x69\x9F\xC5\xAA\x18\x1D\x5D\x20\xE1\x00
Instructions:
Output from running corpus
In this case, the corpus expects eflags to have ZF (Zero flag) set, but the flag is set depending on which core the set of instructions runs on. On a 12900 cores 0-15 are p cores while cores 16-23 are e-cores
The instruction that influences the zero flag in this scenario is the
imul ebx, dword ptr [rdi + 0x1d18aac5], 0xe1205d
instruction.The GDB dump below represents state of the program after the execution of the instructions.
Running on an e-core produces the expected result, the zero flag is set. (Running this on cores 16-23)
However, running on an p-core produces the incorrect result, the zero flag is not set. (Running this on cores 0-15)
According to the intel manual Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2 Page 3-490, it states that for the
imul
instruction "The SF, ZF, AF, and PF flags are undefined."Thus, I believe that this is a false positive because the ZF should not matter in this scenario (whether it is set or not) for the expected output.
Is there a way to filter out this false positive case that silifuzz produces?