https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90346
Bug ID: 90346 Summary: gcc generates the "lfence" instruction on CPUs that don't support it Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: mikulas at artax dot karlin.mff.cuni.cz Target Milestone: --- Host: x86_64-pc-linux-gnu Target: x86_64-pc-linux-gnu Build: x86_64-pc-linux-gnu The built-in function __builtin_speculation_safe_value generates a "lfence" instruction. Unfortunatelly, it doesn't check that the target CPU supports the lfence instruction. GCC should use dummy atomic instruction (such as "lock addl $0, (%esp)" - or some other serializing instruction on CPUs that don't have lfence. Compile this program with "-O3 -m32 -march=pentium2" #include <stddef.h> int array[500]; int f1 (unsigned untrusted_index) { if (untrusted_index < 500) return array[untrusted_index]; return 0; } int f2 (unsigned untrusted_index) { if (untrusted_index < 500) return array[__builtin_speculation_safe_value(untrusted_index)]; return 0; } int f3 (unsigned untrusted_index) { if (untrusted_index < 500) return *__builtin_speculation_safe_value(&array[untrusted_index], NULL); return 0; } The result: 00000000 <f1>: 0: 8b 54 24 04 mov 0x4(%esp),%edx 4: 31 c0 xor %eax,%eax 6: 81 fa f3 01 00 00 cmp $0x1f3,%edx c: 76 02 jbe 10 <f1+0x10> e: c3 ret f: 90 nop 10: 8b 04 95 00 00 00 00 mov 0x0(,%edx,4),%eax 17: c3 ret 18: 90 nop 19: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi 00000020 <f2>: 20: 31 c0 xor %eax,%eax 22: 81 7c 24 04 f3 01 00 cmpl $0x1f3,0x4(%esp) 29: 00 2a: 76 04 jbe 30 <f2+0x10> 2c: c3 ret 2d: 8d 76 00 lea 0x0(%esi),%esi 30: 0f ae e8 lfence 33: 8b 44 24 04 mov 0x4(%esp),%eax 37: 8b 04 85 00 00 00 00 mov 0x0(,%eax,4),%eax 3e: c3 ret 3f: 90 nop 00000040 <f3>: 40: 31 c0 xor %eax,%eax 42: 81 7c 24 04 f3 01 00 cmpl $0x1f3,0x4(%esp) 49: 00 4a: 76 04 jbe 50 <f3+0x10> 4c: c3 ret 4d: 8d 76 00 lea 0x0(%esi),%esi 50: 8b 44 24 04 mov 0x4(%esp),%eax 54: c1 e0 02 shl $0x2,%eax 57: 0f ae e8 lfence 5a: 8b 80 00 00 00 00 mov 0x0(%eax),%eax 60: c3 ret