From a3e285f6dff32d6f56c917d6d187bbac46841bb4 Mon Sep 17 00:00:00 2001 From: Chen Hu Date: Tue, 26 Apr 2022 01:58:22 -0700 Subject: [PATCH] JIT: Add IBT support 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 --- ext/opcache/jit/dynasm/dasm_x86.lua | 2 ++ ext/opcache/jit/zend_jit_x86.dasc | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/ext/opcache/jit/dynasm/dasm_x86.lua b/ext/opcache/jit/dynasm/dasm_x86.lua index fe2cf579b8141..d5eea69e485a7 100644 --- a/ext/opcache/jit/dynasm/dasm_x86.lua +++ b/ext/opcache/jit/dynasm/dasm_x86.lua @@ -1147,6 +1147,8 @@ local map_op = { rep_0 = "F3", repe_0 = "F3", repz_0 = "F3", + endbr32_0 = "F30F1EFB", + endbr64_0 = "F30F1EFA", -- F4: *hlt cmc_0 = "F5", -- F6: test... mb,i; div... mb diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index c4a715b306e57..c1e9f75fb3a56 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -1623,6 +1623,16 @@ static size_t tsrm_tls_offset; || } |.endmacro +|.macro ENDBR +||#if defined (__CET__) && (__CET__ & 1) != 0 +| .if X64 +| endbr64 +| .else +| endbr32 +| .endif +||#endif +|.endmacro + static bool reuse_ip = 0; static bool delayed_call_chain = 0; static uint32_t delayed_call_level = 0; @@ -2292,6 +2302,7 @@ static int zend_jit_hybrid_hot_code_stub(dasm_State **Dst) */ static int zend_jit_hybrid_hot_counter_stub(dasm_State **Dst, uint32_t cost) { + | ENDBR | mov r0, EX->func | mov r1, aword [r0 + offsetof(zend_op_array, reserved[zend_func_info_rid])] | mov r2, aword [r1 + offsetof(zend_jit_op_array_hot_extension, counter)] @@ -2362,6 +2373,7 @@ static int zend_jit_hybrid_hot_trace_stub(dasm_State **Dst) static int zend_jit_hybrid_trace_counter_stub(dasm_State **Dst, uint32_t cost) { + | ENDBR | mov r0, EX->func | mov r1, aword [r0 + offsetof(zend_op_array, reserved[zend_func_info_rid])] | mov r1, aword [r1 + offsetof(zend_jit_op_array_trace_extension, offset)] @@ -3049,6 +3061,7 @@ static int zend_jit_align_func(dasm_State **Dst) static int zend_jit_prologue(dasm_State **Dst) { + | ENDBR if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { | SUB_HYBRID_SPAD } else if (GCC_GLOBAL_REGS) {