SSE/SSE2 instructions in libcrypto after build with CPUTYPE=pentium-mmx

Yep. Here it is :

$ objdump -d testmartin | grep -i endbr

$ objdump -d testmartinPROT | grep -i endbr
  401720:       f3 0f 1e fb             endbr32 
  401750:       f3 0f 1e fb             endbr32

And, of course :

$ ./testmartin

$ ./testmartinPROT 
Illegal instruction (core dumped)
But did you compile it on that actual HW ? I was curious myself so I connected my old jig I use for some stuff. The oldest I've got is Celeron 500MHz with 128MB ram. Interestingly enough 13.1 booted up without any issue. But as it's i686 endbr is not a problem.

The next best thing I've got is qemu. I've emulated pentium processor:
CPU: Pentium/P55C (1497.62-MHz 586-class CPU)
  Origin="GenuineIntel"  Id=0x543  Family=0x5  Model=0x4  Stepping=3
But it has no problem with the endbr instruction. I was not able to find a way to disable it.
But did you compile it on that actual HW ?

Yes :

$ sysctl -a | egrep -i 'hw.machine|hw.model|hw.ncpu'
hw.machine: i386
hw.model: Pentium/P55C
hw.ncpu: 1
hw.machine_arch: i386

$ grep -A 4 CPU /var/run/dmesg.boot
CPU: Pentium/P55C (233.87-MHz 586-class CPU)
  Origin="GenuineIntel"  Id=0x543  Family=0x5  Model=0x4  Stepping=3
real memory  = 268435456 (256 MB)
avail memory = 232763392 (221 MB)

If I understand correctly, the -fcf-protection option generates an endbr32 instruction which only exists with i686+ and should not be used with an i586/i486/i386 CPU. -fcf-protection is used by default if --disable-hardening is not specified with the configure script.

Is it a compiler issue that shouldn't allow the option if -march < i686 ?
Or a sudo autoconf file issue that shouldn't always use -fcf-protection ?
Or a port issue that should make --disable-hardening an option for the build ?
This is interesting. While qemu does emulate CPU seemingly the same as you have it can still understand endbr instruction. This has something to do with the guest isolation probably.

In my opinion clang should not generate code on your machine for your CPU that is not able to run (with -march at least). But that's only my opinion, this would be a question for clang devel team. Not sure if anybody would bother to check this for your CPU but if they are willing to share their opinion on this, that would be great.

Yes, correct, it's the flow control mechanism that mitigates certain types of exploits (use of indirect jumps). There are other mitigations that should be allowed (stack guard for example) and I'm not sure what does --disable-hardening macro do. In this scenario you'd be better off with gcc.

My Makefile I used for test:
CFLAGS=-g -march=i586 -fcf-protection

test:    test.c
    cc $(CFLAGS) -o test test.c

    rm -f *.o test
I was googling around and indeed, for gcc this was a bug filled and fixed 98667. The resolution is what I'd expect: x86: Error on -fcf-protection with incompatible target.

I don't have high hopes anybody is going to touch it but I did open a PR for it: PR 267401.
I guess these CPUs are not used that often any more. And it seems virtual ones emulate things they should not.


Staff member
You might be surprised. I once reported an illegal instruction in a compiler because it was trapping in valgrind but not on silicon.