Over the last few weeks I have been developing an LLVM Utility pass to check a program at the IR level for Spectre variant 1 (bounds check bypass) vulnerabilities. The pass was initially developed for internal use. However, as it has proved to be useful we have decided to share it with the LLVM community.
The pass currently must be enabled with -mllvm -enable-sceptre. When it finds a vulnerability it outputs a diagnostic of the form:
warning: spectre.c:10:10: in function array1_load: found vulnerable load
note: inlined into function foo at: spectre.c:19:24
note: bounds check with index “index” is at: spectre.c:6:16: in function is_valid_idx
note: inlined into function foo at: spectre.c:18:6
As it runs after inlining it must be ran at –O1 or above (recommendation is to run it at –O2). It’s also enabled in the LTO pipeline so can detect cases of cross module inlining with -flto.
The code is on phabricator:
Paul Kocher (one of the researchers who wrote the Spectre paper) recently had a look at Microsoft’s /Qspectre flag:
Out of 15 examples Microsoft’s compiler was able to detect 2 (admittedly some of the examples are very hard to detect without huge numbers of false positives). The Sceptre detector in its current form detects 9/15 (one of the examples leaks the value, and is detected with –sceptre-show-call-escapes, and another is detected with –sceptre-find-second-load=false).
The pass is still under development. However, as mentioned earlier even in its current form it has proved to be useful. Comments welcome.