Hi! I would like to ask for suggestions about the best way to enable PAC/BTI support in glibc and GCC on Debian.
PAC and BTI are two useful Arm security features, see this recent presentation at the Mini Debconf for all details: [0] In order to properly support PAC/BTI in Debian we need to enable support in both GCC and glibc. An executable is marked as BTI compatible only if all the execution units of the program are BTI compatible. See pages 10-11 on the presentation slides. [1] One can easily verify if things work fine by building a test program as follows: gcc -mbranch-protection=standard -z force-bti /tmp/test.c On systems where both GCC and glibc support PAC/BTI, the command above returns no output, and the resulting executable has "BTI, PAC" listed in the output of readelf -n: readelf -n a.out | grep Properties Properties: AArch64 feature: BTI, PAC If PAC/BTI support is not enabled in GCC/glibc, building the program with -z force-bti returns something like: /usr/bin/ld: /usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/Scrt1.o: warning: BTI turned on by -z force-bti when all inputs do not have BTI in NOTE section. /usr/bin/ld: /usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/crti.o: warning: BTI turned on by -z force-bti when all inputs do not have BTI in NOTE section. /usr/bin/ld: /usr/lib/gcc/aarch64-linux-gnu/13/crtbeginS.o: warning: BTI turned on by -z force-bti when all inputs do not have BTI in NOTE section. /usr/bin/ld: /usr/lib/gcc/aarch64-linux-gnu/13/crtendS.o: warning: BTI turned on by -z force-bti when all inputs do not have BTI in NOTE section. /usr/bin/ld: /usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/crtn.o: warning: BTI turned on by -z force-bti when all inputs do not have BTI in NOTE section. To add BTI to the NOTE section of the above, we would need to build both GCC and glibc with -mbranch-protection=standard. For gcc-13 I have proposed https://bugs.debian.org/1055711. Given that glibc in Debian is built with gcc-12, we will also need to build gcc-12 with -mbranch-protection=standard. When it comes to glibc itself, there is a configure check to enable BTI support [2], and it uses CFLAGS as passed to ./configure. I have done the following here on my arm64 machine: - built gcc-12 with PAC/BTI (see #1055711) - built glibc with the PAC/BTI enabled gcc-12 and the attached patch The resulting GCC and glibc have working PAC/BTI support. There is maybe a better way in glibc and GCC to achieve the same goal, do you maintainers have any suggestions? Thanks! Emanuele [0] https://wiki.debian.org/DebianEvents/gb/2023/MiniDebConfCambridge/Capper [1] https://wiki.debian.org/DebianEvents/gb/2023/MiniDebConfCambridge/Capper?action=AttachFile&do=view&target=miniconf-2023-PAC-and-BTI.pdf [2] https://sources.debian.org/src/glibc/2.37-12/sysdeps/aarch64/configure/?hl=184#L188
diff -Nru glibc-2.37/debian/rules glibc-2.37/debian/rules --- glibc-2.37/debian/rules 2023-10-02 22:29:12.000000000 +0200 +++ glibc-2.37/debian/rules 2023-11-28 10:35:40.000000000 +0100 @@ -112,6 +112,11 @@ BUILD_CFLAGS = -O2 -g -fdebug-prefix-map=$(CURDIR)=. HOST_CFLAGS = -pipe -O2 -g -fdebug-prefix-map=$(CURDIR)=. $(call xx,extra_cflags) +ifeq ($(DEB_BUILD_ARCH),arm64) + HOST_CFLAGS += -mbranch-protection=standard + HOST_CXXFLAGS += -mbranch-protection=standard +endif + # 32-bit MIPS builders have a 2GB memory space. This is not enough to # build test-tgmath3.o with GCC, unless tweaking the garbage collector. ifeq ($(findstring mips,$(DEB_BUILD_ARCH))-$(DEB_BUILD_ARCH_BITS), mips-32) diff -Nru glibc-2.37/debian/rules.d/build.mk glibc-2.37/debian/rules.d/build.mk --- glibc-2.37/debian/rules.d/build.mk 2023-10-02 22:29:12.000000000 +0200 +++ glibc-2.37/debian/rules.d/build.mk 2023-11-28 10:35:40.000000000 +0100 @@ -97,6 +97,7 @@ echo -n "Build started: " ; date --rfc-2822; \ echo "---------------"; \ cd $(DEB_BUILDDIR) && \ + $(if $(filter -mbranch-protection=standard,$(shell dpkg-buildflags --get CFLAGS)),CFLAGS=-mbranch-protection=standard) \ CC="$(call xx,CC)" \ CXX=$(if $(filter nocheck,$(DEB_BUILD_OPTIONS)),:,"$(call xx,CXX)") \ MIG="$(call xx,MIG)" \