C++ Logo

std-proposals

Advanced search

Re: [std-proposals] #include <debug>

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Sun, 1 Dec 2024 20:45:55 +0000
On Fri, Nov 29, 2024 at 4:41 PM Thiago Macieira wrote:
>
> > Sounds like you take the designers of Control Flow Enforcement as some
> > sort of authority.
>
> Yes. This functionality is already in the market and has been for 2 years (my
> laptop has it), the hardware functionality cannot be changed any more.


I've done a little web-searching on this. Here's what I found about
Intel Control-flow Enforcement:

"The shadow stack stores a copy of the return address of each CALL. On
a RET, the processor checks if the return address stored in the normal
stack and shadow stack are equal. If the addresses are not equal, the
processor generates an INT #21 (Control Flow Protection Fault)."

So the two instructions being monitored by the central processing unit
are CALL and RET.

The CALL instruction can be broken into two instructions. The
following instructin:

    call rax

can be turned into:

    push rip+2
    jmp rax

Similarly the RET instruction can be turned into:

    pop r11
    jmp r11

Therefore, if you want to compile a source file to an object file
replacing all call's with push+jmp, and all ret's with pop+jmp, then
the GNU compiler could have a new command line option:

    g++ -o frog.o -c frog.c --call-push-jmp

An alternative would be to have a new function attribute called
"call_push_jmp" as follows:

    extern int Func(int, double) __attribute__((call_push_jmp));

This would allow us to get around the control-flow enforcement when we
want to (such as when debugging). I might post this to the GNU mailing
list now.

Received on 2024-12-01 20:46:03