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)" \

Reply via email to