Skip to content

Commit

Permalink
Add IBT support for fiber
Browse files Browse the repository at this point in the history
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 fiber:
1. Add endbr32/64 in assembly
2. Inform compiler jump_fcontext may return via indirect branch

Furthermore:
gcc support CET since v8.1 and set it to default since gcc 11. That is,
the ELF header of sapi/cli/php has a property named IBT. However, such
property is lost since PHP8.1 because the assembly introduced by Fiber.
This commit also fixes this.

Closes GH-8339

Signed-off-by: Chen, Hu <hu1.chen@intel.com>
Co-authored-by: Christoph M. Becker <cmbecker69@gmx.de>
  • Loading branch information
2 people authored and ramsey committed May 25, 2022
1 parent 2236b2d commit 040a37d
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 1 deletion.
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.1.8

- Core:
. Fixed bug GH-8338 (Intel CET is disabled unintentionally). (Chen, Hu)

- MBString:
. mb_detect_encoding recognizes all letters in Czech alphabet (alexdowad)
. mb_detect_encoding recognizes all letters in Hungarian alphabet (alexdowad)
Expand Down
6 changes: 6 additions & 0 deletions Zend/asm/jump_x86_64_sysv_elf_gas.S
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,18 @@
* *
****************************************************************************************/

# if defined __CET__
# include <cet.h>
# else
# define _CET_ENDBR
# endif
.file "jump_x86_64_sysv_elf_gas.S"
.text
.globl jump_fcontext
.type jump_fcontext,@function
.align 16
jump_fcontext:
_CET_ENDBR
leaq -0x38(%rsp), %rsp /* prepare stack */

#if !defined(BOOST_USE_TSX)
Expand Down
8 changes: 8 additions & 0 deletions Zend/asm/make_x86_64_sysv_elf_gas.S
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,18 @@
* *
****************************************************************************************/

# if defined __CET__
# include <cet.h>
# else
# define _CET_ENDBR
# endif
.file "make_x86_64_sysv_elf_gas.S"
.text
.globl make_fcontext
.type make_fcontext,@function
.align 16
make_fcontext:
_CET_ENDBR
/* first arg of make_fcontext() == top of context-stack */
movq %rdi, %rax

Expand Down Expand Up @@ -66,11 +72,13 @@ make_fcontext:
trampoline:
/* store return address on stack */
/* fix stack alignment */
_CET_ENDBR
push %rbp
/* jump to context-function */
jmp *%rbx

finish:
_CET_ENDBR
/* exit code is zero */
xorq %rdi, %rdi
/* exit application */
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_fibers.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ typedef struct {

/* These functions are defined in assembler files provided by boost.context (located in "Zend/asm"). */
extern void *make_fcontext(void *sp, size_t size, void (*fn)(boost_context_data));
extern boost_context_data jump_fcontext(void *to, zend_fiber_transfer *transfer);
extern ZEND_INDIRECT_RETURN boost_context_data jump_fcontext(void *to, zend_fiber_transfer *transfer);
#endif

ZEND_API zend_class_entry *zend_ce_fiber;
Expand Down
6 changes: 6 additions & 0 deletions Zend/zend_portability.h
Original file line number Diff line number Diff line change
Expand Up @@ -679,4 +679,10 @@ extern "C++" {
# define ZEND_VOIDP(ptr) (ptr)
#endif

#if defined(__GNUC__) && ZEND_GCC_VERSION >= 9000
# define ZEND_INDIRECT_RETURN __attribute__((__indirect_return__))
#else
# define ZEND_INDIRECT_RETURN
#endif

#endif /* ZEND_PORTABILITY_H */

0 comments on commit 040a37d

Please sign in to comment.