-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fixed bug #8338 (Intel CET is disabled unintentionally since PHP-8.1.0) #8339
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
cc @trowski |
I know nothing about Intel CET, but at a glance this seems to make sense. |
Zend/zend_fibers.c
Outdated
@@ -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 boost_context_data jump_fcontext(void *to, zend_fiber_transfer *transfer) __attribute__ ((__indirect_return__)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
__attribute__ ((__indirect_return__))
is not necessarily supported (see the failing CI builds), and as such must not be applied uncoditionally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attribute ((indirect_return)) is relatively new gcc attreibute. So I need figure out other fix.
How about insert one line inline assembly after jump_fcontext(). Maybe that's too ugly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it is okay to only enable shstk
if __attribute__((indirect_return))
(or equivalent) is supported by the compiler. Those interested in best security practices would need to use a newish compiler version, but that may be okay.
I wouldn't know if something like __attribute__((indirect_return))
is supported by MSVC. CET support is generally available there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on my current understanding (maybe it's not correct), there are no such attribute for shadow stack.
Basically, the compiler such as gcc take care of shadow stack. No special treatment is needed for application.
But Fiber or applications use makecontext() are exception. They make context (i.e., they maintain stack) by themselves instead of gcc/libc. So they also need creating a shadow stack which requires kernel support. Such kernel patch is under review.
Zend/asm/jump_x86_64_sysv_elf_gas.S
Outdated
@@ -30,6 +30,7 @@ | |||
.type jump_fcontext,@function | |||
.align 16 | |||
jump_fcontext: | |||
endbr64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm not mistaken, these assembler files are re-used from the boost libraries, and as such it would probably be a good idea to provide these modifications upstream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this file is imported from boostorg/context, so please do provide any changes here upstream as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I will try to provide CET support to boostorg/context as well and then echo here.
Hi @trowski,
Below supports are needed to enable CET:
@hjl-tools has a nice explanation for CET in LPC. https://lpc.events/event/2/contributions/147/attachments/72/83/CET-LPC-2018.pdf |
Thanks community for the detailed review. Now the reviews focus on Fiber part support for "indirect branch tracking". |
Would it be better to do separate PR at this point tough ? |
can this target PHP 8.1 and is the Intel CET security feature supported also with MSVC? |
See https://docs.microsoft.com/en-us/cpp/build/reference/cetcompat?view=msvc-170. |
added to #8392 to see if tests pass can the compiler default flags be specified somewhere so pure |
|
The following patch should do for VS 2019 and up: win32/build/confutils.js | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/win32/build/confutils.js b/win32/build/confutils.js
index 9bf1bf2814..1571d1964f 100644
--- a/win32/build/confutils.js
+++ b/win32/build/confutils.js
@@ -3401,10 +3401,13 @@ function toolset_setup_common_ldlags()
ADD_FLAG("PHP_LDFLAGS", "/nodefaultlib:libcmt");
if (VS_TOOLSET) {
- if (VCVERS >= 1900) {
- if (PHP_SECURITY_FLAGS == "yes") {
+ if (PHP_SECURITY_FLAGS == "yes") {
+ if (VCVERS >= 1900) {
ADD_FLAG('LDFLAGS', "/GUARD:CF");
}
+ if (VCVERS >= 1920) {
+ ADD_FLAG('LDFLAGS', "/CETCOMPAT");
+ }
}
if (PHP_VS_LINK_COMPAT != "no") {
// Allow compatible IL versions, do not require an exact match. |
this PR should target PHP 8.1 (or maybe 8.0, but the desc claims the support is broken since PHP 8.1) |
I thinks it targets PHP8.1. If the user want to compile the PHP to enable CET, he should specify gcc "-fcf-protection" option explicitly. Below is an example: However, PHP 8.1 introduces some hand-coded assemblers (from Fiber) which ignores/breaks this gcc option. With this PR, if "-fcf-protection" is detected, linker options will be added to make sure the final PHP bin is CET enabled. |
Per @devnexen's comments, I separate the patches. Now this PR focus on Fiber part. It's based on merged PR in boost: boostorg/context#199. This patch passes test on a full CET environment/stack at a CET enabled Intel CPU. Without the patch, fiber test will fail because IBT violation.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than the minor nit about attribute placement, this LGTM.
If this is a bug in PHP 8.1, please change the base branch to PHP-8.1. Thanks! |
Hi @ramsey, I saw this issue in fiber since PHP 8.1. It's also in current master. For such case, shall we change base branch to 8.1? |
Current master is 8.2.0-dev, so if it exists in both PHP-8.1 and master, then you need to target PHP-8.1 and we will merge it up into master. If the bug also exists in PHP-8.0, then you should target PHP-8.0 instead. |
Just to be sure, adding |
"No, it won't change ABI." |
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. Signed-off-by: Chen, Hu <hu1.chen@intel.com> Co-authored-by: Christoph M. Becker <cmbecker69@gmx.de>
Hi @ramsey, I am new on the flow of github. Sorry for the inconvenience. |
The proper way to do this for php-src is to first rebase the branch onto the new target branch (PHP-8.1), then force-push, and only then change the target branch via UI. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
Intel Control Flow Enforcement Technology (CET) is enabled by default
since gcc v8.1. With CET, gcc emits following processor-specific program
property types in .note.gnu.property section:
Such properties are there before PHP-8.1.0.
$ sudo readelf -n sapi/cli/php
Displaying notes found in: .note.gnu.property
Owner Data size Description
GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
Properties: x86 feature: IBT, SHSTK
x86 ISA needed: x86-64-baseline
However, the properties are missing since PHP-8.1.0.
$ sudo readelf -n sapi/cli/php
Displaying notes found in: .note.gnu.property
Owner Data size Description
GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
Properties: x86 ISA needed: x86-64-baseline
This is caused by commit c276c16 "Implement Fibers" which introduces
some assembly files such as jump_x86_64_sysv_elf_gas.S and
make_x86_64_sysv_elf_gas.S. The object files of such assembly miss
.note.gnu.property section and thus the final output files miss it too.
Fix this via adding linker option.
Signed-off-by: Chen, Hu hu1.chen@intel.com