-control_flow_integrity [Professional Edition only] [V1.07.00 or later]


This option generates code for the detection of illegal indirect function calls.

[Specification format]

-control_flow_integrity

 

-

Interpretation when omitted

Code for the detection of illegal indirect function calls is not generated.

[Detailed description]

-

This option generates code for the detection of illegal indirect function calls.

When this option is specified, code for the following processing is generated in the C source program.

(1)

The __control_flow_integrity checking function is called with an indirect calling address as an argument immediately before indirect function calls.

(2)

Within the checking function, the address given as the argument is checked against a list of the addresses of functions (hereafter referred to as the function list) which may be indirectly called. If the list does not include the address, the __control_flow_chk_fail function will be called since this is regarded as an illegal indirect function call.

The correctness of processing to change the flow of the program, such as through indirect function calls, is referred to as control flow integrity (CFI), and CFI techniques are used to verify this.

-

A checking function is defined as follows and provided as library functions.

void __control_flow_integrity(void *addr);

Calling the checking function in the same way as normal functions is prohibited.

-

The compiler automatically extracts the information on the functions which may be indirectly called from the C source program. The linker consolidates that information in creating the function list. For the linker to create a function list, the -CFI link option must be specified.

For details, refer to section 2.5.3 Link options.

-

The __control_flow_chk_fail function contains code for the processing which is to be executed when an illegal indirect function call is detected. The user must define this function.

Note the following when defining the __control_flow_chk_fail function.

-

Specify void as the type of the return value and parameter.

-

Do not define the function as static.

-

Calling the __control_flow_chk_fail function in the same way as a normal function is prohibited.

-

The __control_flow_chk_fail function is not for the creation of code for detecting illegal indirect function calls.

-

In the __control_flow_chk_fail function, note that execution must not be returned to the checking function, for example, by calling abort() to terminate the program.

-

If the -pic option is specified at the same time, an error will occur.

 

Example:

-

<C source code>

#include <stdlib.h>
 
int glb;
 
void __control_flow_chk_fail(void) 
{
    abort();
}
 
void func1(void) // Added to the function list.
{
    ++glb;
}
 
void func2(void) // Not added to the function list.
{
    --glb;
}
 
void (*pf)(void) = func1;
 
void main(void)
{
    pf(); // Indirect call of the function func1.
    func2();
}

 

-

<Output code>

When -S -control_flow_integrity is specified for compilation

___control_flow_chk_fail:
    .stack ___control_flow_chk_fail = 4
    prepare 0x00000001, 0x00000000
    jarl _abort, r31
    dispose 0x00000000, 0x00000001, [r31]
_func1:
    .stack _func1 = 0
    movhi HIGHW1(#_glb), r0, r2
    ld.w LOWW(#_glb)[r2], r5
    add 0x00000001, r5
    st.w r5, LOWW(#_glb)[r2]
    jmp [r31]
_func2:
    .stack _func2 = 0
    movhi HIGHW1(#_glb), r0, r2
    ld.w LOWW(#_glb)[r2], r5
    add 0xFFFFFFFF, r5
    st.w r5, LOWW(#_glb)[r2]
    jmp [r31] 
_main:
    .stack _main = 8
    prepare 0x00000041, 0x00000000
    movhi HIGHW1(#_pf), r0, r20
    ld.w LOWW(#_pf)[r20], r20
    mov r20, r6
    jarl ___control_flow_integrity, r31 ; Call the checking function.
    jarl [r20], r31 ; Indirect call of the function func1.
    jarl _func2, r31 ; Direct call of the function func2.
    dispose 0x00000000, 0x00000041, [r31] 
    .section .bss, bss
    .align 4
_glb:
    .ds (4)
    .section .data, data
    .align 4
_pf:
    .dw #_func1
    .section .const, const