Skip to content

Fix Intel CET / SHSTK support in fibers - #14027

Open
arnaud-lb wants to merge 2 commits into
php:masterfrom
arnaud-lb:fix-shstk
Open

arnaud-lb wants to merge 2 commits into
php:masterfrom
arnaud-lb:fix-shstk

Conversation

@arnaud-lb

@arnaud-lb arnaud-lb commented Apr 21, 2024 •

Copy link
Copy Markdown
Member

This fixes SHSTK support in fibers:

  • The syscall number for map_shadow_stack has changed since initial support was added. I update the syscall number and use the SYS_map_shadow_stack macro instead of the hard coded number when possible. Note: when the configure check is broken, SHSTK is not disabled. Instead, SHSTK handling is not added, causing fibers to crash. So there is no risk of disabling a security feature by breaking this check.
  • make_fcontext/jump_fcontext was broken due to accidental duplication of shadow stack handling
  • Set the the shadow stack to the same size as the normal stack, as in the worse case the shadow stack needs as much space. This matches what the kernel does for the main stack. This size is excluding the guard page the kernel adds.
  • Enable SHSTK in CI. For now this should only check that we can build with -fcf-protection, and that the linker adds the SHSTK flag on the binary (cet-report=error). The glibc version used in CI will not enable SHSTK at runtime, but I believe it will in Ubuntu 24.

This can be tested with a kernel >= 6.6 and glibc >= 2.39, when compiling with CFLAGS=-fcf-protection=full LDFLAGS=-Wl,-z,cet-report=error, and running with GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK.

Check that the binary was compiled with SHSTK:

$ readelf -n sapi/cli/php | grep -a SHSTK
Properties: x86 feature: IBT, SHSTK

Check CPU and kernel support:

$ grep user_shstk /proc/cpuinfo
flags		: [...] user_shstk [...]

Check that ld enables SHSTK:

$ GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK strace sapi/cli/php -r '' 2>&1 | grep ARCH_SHSTK
arch_prctl(ARCH_SHSTK_ENABLE, 0x1)      = 0
arch_prctl(ARCH_SHSTK_STATUS, 0x7ffe4933a418) = 0
arch_prctl(ARCH_SHSTK_LOCK, 0xffffffffffffffff) = 0

See https://docs.kernel.org/next/x86/shstk.html
See https://www.phoronix.com/news/Glibc-Intel-CET-Shadow-Stack

@arnaud-lb
arnaud-lb changed the base branch from master to PHP-8.3 April 21, 2024 18:29
@arnaud-lb
arnaud-lb marked this pull request as ready for review April 23, 2024 10:00
@arnaud-lb
arnaud-lb requested a review from devnexen April 23, 2024 10:01
@devnexen

Copy link
Copy Markdown
Member

make_fcontext/jump_fcontext was broken due to accidental duplication of shadow stack handling

If that's the case, you should definitively upstream your bug fix.

@arnaud-lb

Copy link
Copy Markdown
Member Author

I planed to do so, but do you confirm the duplication in boostorg/context#248 was a mistake?

@devnexen

Copy link
Copy Markdown
Member

yes :)

@devnexen

devnexen commented Oct 7, 2024 •

Copy link
Copy Markdown
Member

can t reproduce the issues on CI locally, any luck ? nvm I actually can with my other laptop.

@arnaud-lb

Copy link
Copy Markdown
Member Author

Oh, I didn't notice this. I will check

@arnaud-lb

Copy link
Copy Markdown
Member Author

The LINUX_X64_RELEASE_NTS job is the last one running Ubuntu 22.04 I believe, and in this version the Glibc loader doesn't enable SHSTK. The program crashes on the rstorssp instruction because SHSTK is not enabled, if I understand correctly. This is not ideal, as it means we can not build with -fcf-protection in case the runtime may not enable SHSTK. Maybe the asm should skip the SSP setup/restore when SHSTK is not enabled.

@devnexen

devnexen commented Oct 8, 2024

Copy link
Copy Markdown
Member

The LINUX_X64_RELEASE_NTS job is the last one running Ubuntu 22.04 I believe, and in this version the Glibc loader doesn't enable SHSTK. The program crashes on the rstorssp instruction because SHSTK is not enabled, if I understand correctly. This is not ideal, as it means we can not build with -fcf-protection in case the runtime may not enable SHSTK. Maybe the asm should skip the SSP setup/restore when SHSTK is not enabled.

I think you re right, I get a SIGILL for those instructions in one intel machine but not the other (more modern distro).

@arnaud-lb
arnaud-lb changed the base branch from PHP-8.3 to master July 6, 2026 09:09
* Syscall number for map_shadow_stack has changed since initial support was
  added.
* Use SYS_map_shadow_stack instead of hard-coded number when possible
The shadow stack may need as much space as the fiber stack in the worse case, so
allocate a shadow stack the same size as the fiber stack. This matches what the
kernel does for the main stack.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants