node icon indicating copy to clipboard operation
node copied to clipboard

build: enable pointer authentication on arm64 for branch protection

Open jgowdy opened this issue 1 year ago • 6 comments

What is the problem this feature will solve?

ARM64v8.3 supports Pointer Authentication with the PACIASP and AUTIASP instructions which are interpreted as NOP instructions on pre-8.3 architectures. These instructions sign the stack pointer and validate the stack pointer prior to return to mitigate return oriented programming.

GCC supports these options on arm64 / aarch64. The legacy option was -msign-return-address=[all | non-leaf | none] and the modern option is -mbranch-protection=none|standard|pac-ret[+leaf+b-key]|bti

I would like to suggest that the arm64 build be modified to include -mbranch-protection=pac-ret with the -march being set to ARMv8.2 or earlier or not configured, so that GCC will generate PACIASP and AUTIASP instructions. It is critical that -march=armv8.3 or higher not be passed or the non-backwards compatible RETAA instruction will be generated.

What is the feature you are proposing to solve the problem?

The benefit of enabling pointer authentication for the stack pointer on ARM64 would be to mitigate return oriented programming attacks against the Node.js runtime.

What alternatives have you considered?

Presently we are pursuing custom compiles of the Node.js runtime for the new Graviton3 CPUs that support pointer authentication in AWS.

As feature requested in: https://github.com/nodejs/node/issues/42888

jgowdy avatar May 24 '22 22:05 jgowdy

CI: https://ci.nodejs.org/job/node-test-pull-request/44156/

nodejs-github-bot avatar May 25 '22 00:05 nodejs-github-bot

Related failures: https://ci.nodejs.org/job/node-test-commit-arm/41957/nodes=rhel8-arm64/console https://ci.nodejs.org/job/node-test-commit-arm/41957/nodes=ubuntu1804-arm64/console https://ci.nodejs.org/job/node-test-commit-arm-debug/2195/nodes=ubuntu1804-arm64/console

02:30:42   ccache gcc-8 -o /home/iojs/build/workspace/node-test-commit-arm-debug/out/Release/obj.target/openssl/deps/openssl/openssl/ssl/ssl_ciph.o ../deps/openssl/openssl/ssl/ssl_ciph.c '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-DNODE_OPENSSL_HAS_QUIC' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DOPENSSL_NO_HW' '-DOPENSSL_API_COMPAT=0x10100001L' '-DSTATIC_LEGACY' '-DNDEBUG' '-DOPENSSL_USE_NODELETE' '-DOPENSSL_BUILDING_OPENSSL' '-DECP_NISTZ256_ASM' '-DKECCAK1600_ASM' '-DOPENSSL_BN_ASM_MONT' '-DOPENSSL_CPUID_OBJ' '-DPOLY1305_ASM' '-DSHA1_ASM' '-DSHA256_ASM' '-DSHA512_ASM' '-DVPAES_ASM' '-DOPENSSL_PIC' '-DMODULESDIR="/home/iojs/build/workspace/node-test-commit-arm-debug/out/Debug/obj.target/deps/openssl/lib/openssl-modules"' '-DOPENSSLDIR="/home/iojs/build/workspace/node-test-commit-arm-debug/out/Debug/obj.target/deps/openssl"' '-DENGINESDIR="/dev/null"' '-DTERMIOS' -I../deps/openssl/openssl -I../deps/openssl/openssl/include -I../deps/openssl/openssl/crypto -I../deps/openssl/openssl/crypto/include -I../deps/openssl/openssl/crypto/modes -I../deps/openssl/openssl/crypto/ec/curve448 -I../deps/openssl/openssl/crypto/ec/curve448/arch_32 -I../deps/openssl/openssl/providers/common/include -I../deps/openssl/openssl/providers/implementations/include -I../deps/openssl/config -I../deps/openssl/config/archs/linux-aarch64/asm -I../deps/openssl/config/archs/linux-aarch64/asm/include -I../deps/openssl/config/archs/linux-aarch64/asm/crypto -I../deps/openssl/config/archs/linux-aarch64/asm/crypto/include/internal -I../deps/openssl/config/archs/linux-aarch64/asm/providers/common/include  -mbranch-protection=pac-ret -pthread -Wall -Wextra -Wno-unused-parameter -Wa,--noexecstack -Wall -O3 -pthread -Wall -O3 -Wno-missing-field-initializers -Wno-old-style-declaration -O3 -fno-omit-frame-pointer  -MMD -MF /home/iojs/build/workspace/node-test-commit-arm-debug/out/Release/.deps//home/iojs/build/workspace/node-test-commit-arm-debug/out/Release/obj.target/openssl/deps/openssl/openssl/ssl/ssl_ciph.o.d.raw   -c
02:30:42 gcc-8: error: unrecognized command line option '-mbranch-protection=pac-ret'; did you mean '-fcf-protection=none'?

targos avatar May 25 '22 05:05 targos

Related failures: https://ci.nodejs.org/job/node-test-commit-arm/41957/nodes=rhel8-arm64/console https://ci.nodejs.org/job/node-test-commit-arm/41957/nodes=ubuntu1804-arm64/console https://ci.nodejs.org/job/node-test-commit-arm-debug/2195/nodes=ubuntu1804-arm64/console

02:30:42   ccache gcc-8 -o /home/iojs/build/workspace/node-test-commit-arm-debug/out/Release/obj.target/openssl/deps/openssl/openssl/ssl/ssl_ciph.o ../deps/openssl/openssl/ssl/ssl_ciph.c '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-DNODE_OPENSSL_HAS_QUIC' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DOPENSSL_NO_HW' '-DOPENSSL_API_COMPAT=0x10100001L' '-DSTATIC_LEGACY' '-DNDEBUG' '-DOPENSSL_USE_NODELETE' '-DOPENSSL_BUILDING_OPENSSL' '-DECP_NISTZ256_ASM' '-DKECCAK1600_ASM' '-DOPENSSL_BN_ASM_MONT' '-DOPENSSL_CPUID_OBJ' '-DPOLY1305_ASM' '-DSHA1_ASM' '-DSHA256_ASM' '-DSHA512_ASM' '-DVPAES_ASM' '-DOPENSSL_PIC' '-DMODULESDIR="/home/iojs/build/workspace/node-test-commit-arm-debug/out/Debug/obj.target/deps/openssl/lib/openssl-modules"' '-DOPENSSLDIR="/home/iojs/build/workspace/node-test-commit-arm-debug/out/Debug/obj.target/deps/openssl"' '-DENGINESDIR="/dev/null"' '-DTERMIOS' -I../deps/openssl/openssl -I../deps/openssl/openssl/include -I../deps/openssl/openssl/crypto -I../deps/openssl/openssl/crypto/include -I../deps/openssl/openssl/crypto/modes -I../deps/openssl/openssl/crypto/ec/curve448 -I../deps/openssl/openssl/crypto/ec/curve448/arch_32 -I../deps/openssl/openssl/providers/common/include -I../deps/openssl/openssl/providers/implementations/include -I../deps/openssl/config -I../deps/openssl/config/archs/linux-aarch64/asm -I../deps/openssl/config/archs/linux-aarch64/asm/include -I../deps/openssl/config/archs/linux-aarch64/asm/crypto -I../deps/openssl/config/archs/linux-aarch64/asm/crypto/include/internal -I../deps/openssl/config/archs/linux-aarch64/asm/providers/common/include  -mbranch-protection=pac-ret -pthread -Wall -Wextra -Wno-unused-parameter -Wa,--noexecstack -Wall -O3 -pthread -Wall -O3 -Wno-missing-field-initializers -Wno-old-style-declaration -O3 -fno-omit-frame-pointer  -MMD -MF /home/iojs/build/workspace/node-test-commit-arm-debug/out/Release/.deps//home/iojs/build/workspace/node-test-commit-arm-debug/out/Release/obj.target/openssl/deps/openssl/openssl/ssl/ssl_ciph.o.d.raw   -c
02:30:42 gcc-8: error: unrecognized command line option '-mbranch-protection=pac-ret'; did you mean '-fcf-protection=none'?

Let me try using the previous version of the option since we are building with gcc-8, -msign-return-address=all

jgowdy avatar May 25 '22 15:05 jgowdy

CI: https://ci.nodejs.org/job/node-test-pull-request/44162/

nodejs-github-bot avatar May 25 '22 18:05 nodejs-github-bot

It seems there's a failure with the Windows compile, but I'm not sure how that would be related to this PR. The Linux build with the -msign-return-address=all does appear to work now. Can you advise on the failure here? Thanks!

jgowdy avatar May 25 '22 19:05 jgowdy

All checks passed after re-running post rebase.

jgowdy avatar Aug 09 '22 21:08 jgowdy

Automated workflows are only a subset of the checks. I requested a new full CI run.

targos avatar Aug 10 '22 12:08 targos

CI: https://ci.nodejs.org/job/node-test-pull-request/45968/

nodejs-github-bot avatar Aug 10 '22 12:08 nodejs-github-bot

@nodejs/platform-arm

targos avatar Aug 10 '22 13:08 targos

Landed in 938212f3e74a74d0b436941aa24e71425ff666c5

nodejs-github-bot avatar Aug 12 '22 22:08 nodejs-github-bot

Has this flag been deprecated by mbranch-protection in modern versions of gcc? (I'm looking at https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/AArch64-Options.html)

I'm having some trouble cross compiling and hitting this issue specifically. I could probably back off and use version 8, but how will this work long term?

baparham avatar Feb 24 '23 10:02 baparham

Hm, I think maybe the problem is that when cross compiling, the arg (-msign-return-address) looks like it may be getting added to the host compiler args also. Does this sound like a plausible issue?

baparham avatar Feb 24 '23 10:02 baparham

Hm, I think maybe the problem is that when cross compiling, the arg (-msign-return-address) looks like it may be getting added to the host compiler args also. Does this sound like a plausible issue?

See if https://github.com/nodejs/node/pull/45756 fixes cross compiling for you?

richardlau avatar Feb 24 '23 14:02 richardlau

@richardlau thank you 🙏 I'll check it out and see if that solves my issue

baparham avatar Feb 24 '23 14:02 baparham