Skip to content

Commit d8de067

Browse files
authored
JIT: Add IBT support (#8774)
Indirect Branch Tracking (IBT) is part of Intel's Control-Flow Enforcement Technology (CET). IBT is hardware based, forward edge Control-Flow-Integrity mechanism where any indirect CALL/JMP must target an ENDBR instruction or suffer #CP. This commit adds IBT support for JIT: 1. Add endbr32/64 instruction in Dynasm. 2. Insert endbr32/64 in indirect branch target for jitted code. gcc support CET since v8.1 and set it to default since gcc 11. With this commit, endbr is inserted in jitted code if PHP is compiled with "gcc -fcf-protection=full/branch". Signed-off-by: Chen, Hu <hu1.chen@intel.com>
1 parent da52306 commit d8de067

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

ext/opcache/jit/dynasm/dasm_x86.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,8 @@ local map_op = {
11471147
rep_0 = "F3",
11481148
repe_0 = "F3",
11491149
repz_0 = "F3",
1150+
endbr32_0 = "F30F1EFB",
1151+
endbr64_0 = "F30F1EFA",
11501152
-- F4: *hlt
11511153
cmc_0 = "F5",
11521154
-- F6: test... mb,i; div... mb

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1623,6 +1623,22 @@ static size_t tsrm_tls_offset;
16231623
|| }
16241624
|.endmacro
16251625

1626+
|.macro ENDBR
1627+
||#if defined (__CET__) && (__CET__ & 1) != 0
1628+
| .if X64
1629+
| endbr64
1630+
| .else
1631+
| endbr32
1632+
| .endif
1633+
||#endif
1634+
|.endmacro
1635+
1636+
#if defined (__CET__) && (__CET__ & 1) != 0
1637+
# define ENDBR_PADDING 4
1638+
#else
1639+
# define ENDBR_PADDING 0
1640+
#endif
1641+
16261642
static bool reuse_ip = 0;
16271643
static bool delayed_call_chain = 0;
16281644
static uint32_t delayed_call_level = 0;
@@ -2292,6 +2308,7 @@ static int zend_jit_hybrid_hot_code_stub(dasm_State **Dst)
22922308
*/
22932309
static int zend_jit_hybrid_hot_counter_stub(dasm_State **Dst, uint32_t cost)
22942310
{
2311+
| ENDBR
22952312
| mov r0, EX->func
22962313
| mov r1, aword [r0 + offsetof(zend_op_array, reserved[zend_func_info_rid])]
22972314
| mov r2, aword [r1 + offsetof(zend_jit_op_array_hot_extension, counter)]
@@ -2362,6 +2379,7 @@ static int zend_jit_hybrid_hot_trace_stub(dasm_State **Dst)
23622379

23632380
static int zend_jit_hybrid_trace_counter_stub(dasm_State **Dst, uint32_t cost)
23642381
{
2382+
| ENDBR
23652383
| mov r0, EX->func
23662384
| mov r1, aword [r0 + offsetof(zend_op_array, reserved[zend_func_info_rid])]
23672385
| mov r1, aword [r1 + offsetof(zend_jit_op_array_trace_extension, offset)]
@@ -3049,6 +3067,7 @@ static int zend_jit_align_func(dasm_State **Dst)
30493067

30503068
static int zend_jit_prologue(dasm_State **Dst)
30513069
{
3070+
| ENDBR
30523071
if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
30533072
| SUB_HYBRID_SPAD
30543073
} else if (GCC_GLOBAL_REGS) {
@@ -3456,7 +3475,7 @@ static int zend_jit_trace_link_to_root(dasm_State **Dst, zend_jit_trace_info *t,
34563475
prologue_size = 13;
34573476
#endif
34583477
}
3459-
link_addr = (const void*)((const char*)t->code_start + prologue_size);
3478+
link_addr = (const void*)((const char*)t->code_start + prologue_size + ENDBR_PADDING);
34603479

34613480
if (timeout_exit_addr) {
34623481
/* Check timeout for links to LOOP */

0 commit comments

Comments
 (0)