Dear Maintainer, PAC/BTI is a useful Arm security feature, see this recent presentation at the Cambridge 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] I have filed https://bugs.debian.org/1055711 already for gcc-13, which is the default compiler in sid. However, it's important to enable the switch on gcc-12 as well because: a) glibc is currently built with gcc-12, see thread at [2]. The compiler building glibc needs to have the feature turned on b) there are multiple programs in Debian still using GCC 12 c) more generally it would be great for GCC 12 users to also get the feature :-) See attached patch. 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://lists.debian.org/debian-glibc/2023/11/msg00032.html
please also check
- that a cross compiler with this patch has these enabled
- that a cross build of gcc-13 targeting arm64 with this
patch has these enabled
please also check
- that a cross compiler with this patch has these enabled
- that a cross build of gcc-13 targeting arm64 with this
patch has these enabled
Hi Matthias, of the above. As a first attempt I tried setting CFLAGS_FOR_TARGET and CXXFLAGS_FOR_TARGET instead of CFLAGS and CXXFLAGS. That worked fine for cross compilers (ie: building gcc-13-cross), but it broke native builds with the following error: configure:3576: /<<PKGBUILDDIR>>/build-nvptx/./gcc/xgcc -B/<<PKGBUILDDIR>>/build-nvptx/./gcc/ -nostdinc -B/<<PKGBUILDDI R>>/build-nvptx/nvptx-none/newlib/ -isystem /<<PKGBUILDDIR>>/build-nvptx/nvptx-none/newlib/targ-include -isystem /<<PKG BUILDDIR>>/src-nvptx/newlib/libc/include -B/usr/nvptx-none/bin/ -B/usr/nvptx-none/lib/ -isystem /usr/nvptx-none/include -isystem /usr/nvptx-none/sys-include -isystem /<<PKGBUILDDIR>>/build-nvptx/sys-include -o conftest -mbranch-protect ion=standard conftest.c >&5 xgcc: error: unrecognized command-line option '-mbranch-protection=standard' I wonder if this may be related to https://bugs.debian.org/1060075 ? At any rate, the following patch seems to cover all cases: native build, cross compiler build and cross build of the native compiler. I suspect but cannot prove that without #1060075 it would be enough to just unconditionally set CFLAGS_FOR_TARGET and CXXFLAGS_FOR_TARGET. diff -Nru gcc-13-13.2.0/debian/rules2 gcc-13-13.2.0/debian/rules2 --- gcc-13-13.2.0/debian/rules2 2023-12-09 20:15:56.000000000 +0100 +++ gcc-13-13.2.0/debian/rules2 2024-01-04 17:23:48.000000000 +0100 @@ -199,6 +199,22 @@ STAGE1_LDFLAGS = endif +ifeq ($(DEB_TARGET_ARCH),arm64) + ifeq ($(DEB_CROSS),yes) + # Building cross compilers + CFLAGS_FOR_TARGET += -mbranch-protection=standard + CXXFLAGS_FOR_TARGET += -mbranch-protection=standard + else ifneq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE)) + # Cross build of the native compiler + CFLAGS_FOR_TARGET += -mbranch-protection=standard + CXXFLAGS_FOR_TARGET += -mbranch-protection=standard + else + # Native build + CFLAGS += -mbranch-protection=standard + CXXFLAGS += -mbranch-protection=standard + endif +endif + # set CFLAGS/LDFLAGS for the configure step only, maybe be modifed for some target # all other flags are passed to the make step. pass_vars = $(foreach v,$(1),$(if $($(v)),$(v)="$($(v))")) diff -Nru gcc-13-13.2.0/debian/rules.defs gcc-13-13.2.0/debian/rules.defs --- gcc-13-13.2.0/debian/rules.defs 2023-12-14 19:55:12.000000000 +0100 +++ gcc-13-13.2.0/debian/rules.defs 2024-01-04 17:23:48.000000000 +0100 @@ -781,7 +781,7 @@ offload_targets := with_offload_nvptx := endif -ifneq (,$(findstring build-cross, $(build_type))) +ifneq ($(build_type),build-native) offload_targets := with_offload_nvptx := disabled for cross builds endif
Hi Matthias, Both #1055711 and #1057469 have been open for several months now, and they are blocking progress on enabling BTI in Debian (and Ubuntu). See https://wiki.debian.org/ToolChain/PACBTI for the details. Is there any remaining concern? If yes, what can I do to help? If not, can you please get the ball rolling with the next gcc uploads? Thanks, Emanuele
so I now verified that it still works as expected.
The BTI patch looks like this, both for gcc-12 and -13:
diff -Nru gcc-12-12.3.0/debian/rules2 gcc-12-12.3.0/debian/rules2
--- gcc-12-12.3.0/debian/rules2 2023-12-03 18:45:19.000000000 +0100
+++ gcc-12-12.3.0/debian/rules2 2024-05-02 14:25:19.000000000 +0200
@@ -195,6 +195,22 @@
STAGE1_LDFLAGS =
endif
+ifeq ($(DEB_TARGET_ARCH),arm64)
+ ifeq ($(DEB_CROSS),yes)
+ # Building cross compilers
+ CFLAGS_FOR_TARGET += -mbranch-protection=standard
+ CXXFLAGS_FOR_TARGET += -mbranch-protection=standard
+ else ifneq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE))
+ # Cross build of the native compiler
+ CFLAGS_FOR_TARGET += -mbranch-protection=standard
+ CXXFLAGS_FOR_TARGET += -mbranch-protection=standard
+ else
+ # Native build
+ CFLAGS += -mbranch-protection=standard
+ CXXFLAGS += -mbranch-protection=standard
+ endif
+endif
+
# set CFLAGS/LDFLAGS for the configure step only, maybe be modifed for some target
# all other flags are passed to the make step.
pass_vars = $(foreach v,$(1),$(if $($(v)),$(v)="$($(v))"))
These are the checks I performed:
(1) Native aarch64 compiler built on aarch64
On aarch64, I applied the BTI patch to gcc-12's debian/rules2 and built the
package with sbuild. Then I checked that crtbeginS.o and crtendS.o from
libgcc-12-dev had BTI on.
dpkg --extract libgcc-12-dev_12.3.0-18_arm64.deb /tmp/libgcc-12-dev
readelf -n /tmp/libgcc-12-dev/usr/lib/gcc/aarch64-linux-gnu/12/crt{begin,end}S.o | grep BTI
Same procedure and outcome when it comes to gcc-13.
(2) Cross compiler (aarch64) built on x86_64
On x86_64, I did the following in a clean sid chroot:
apt build-dep gcc-12-cross
Apply the BTI patch to /usr/src/gcc-12/debian/rules2
Then, inside the source directory of gcc-12-cross:
export CROSS_ARCHS="amd64 arm64"
debian/rules control
dpkg-buildpackage
At the end of the build process, I checked that crtbeginS.o and crtendS.o as
shipped by libgcc-12-dev-arm64-cross had BTI on.
dpkg --extract libgcc-12-dev-arm64-cross_12.3.0-17_all.deb /tmp/libgcc-cross
readelf -n /tmp/libgcc-cross/usr/lib/gcc-cross/aarch64-linux-gnu/12/crt{begin,end}S.o | grep BTI
Same procedure and outcome when it comes to gcc-13.
(3) Cross build of the native compiler
There are various issues that make cross builds of the native compiler fail.
They are unrelated to the patch proposed here, but I'm mentioning them because
I had to work around them in order to test if a cross build of the native
compiler would carry the BTI property as expected.
The first problem is due to the m2 language, which fails to cross build. I
believe this to be a long standing, known issue (at least Helmut mentioned
being aware of it in the past). Languages can be disabled by passing the
'nolang' build option to DEB_BUILD_OPTIONS, so that's what I have done.
The second issue affects gcc-12 only. Cross building gcc-12 for arm64 on a
amd64 machine fails with an undefined reference error (fprintf_unlocked). Full
logs at https://people.debian.org/~ema/gcc-12_12.3.0-17_arm64.build. Because of
this second problem, I tested a cross-build of the native gcc-13 only, not of
gcc-12.
The third issue affects gcc-13: nvptx does not cross build properly (see
#1060075) but it is enabled in gcc-13 for arm64. To work around this problem
when it comes to gcc-13 I have removed arm64 from the list of nvptx_archs in
debian/rules.defs.
Then, I cross built with m2 disabled:
DEB_BUILD_OPTIONS='nolang=m2' sbuild --host=arm64
At the end of the build process, I verified that crtbeginS.o and crtendS.o from
libgcc-13-dev had BTI on.
dpkg --extract libgcc-13-dev_13.2.0-24.1_arm64.deb /tmp/xxx
readelf -n /tmp/xxx/usr/lib/gcc/aarch64-linux-gnu/13/crt{begin,end}S.o | grep BTI
Hi Matthias, you can find an updated patch attached, it allows to disable the flag by building with DEB_BUILD_MAINT_OPTIONS=hardening=-branch. It does the right thing on libgcc-13-dev built on arm64 as well as libgcc-13-dev-arm64-cross built on amd64. I haven't tested it on cross-builds of the native compiler as that currently fails due to unsatisfied dependencies in sid. That case should work fine too though. Thanks, ema
Double-checked today, cross-builds of the native compiler work as well both with and without the flag. Without -mbranch-protection=standard: DEB_BUILD_MAINT_OPTIONS=hardening=-branch DEB_BUILD_OPTIONS=nolang=m2 sbuild --host=arm64 With -mbranch-protection=standard: DEB_BUILD_OPTIONS=nolang=m2 sbuild --host=arm64 Note that sbuild whitelists a set of variables that are passed into the schroot and all others are dropped, so you'll need the following in ~/.sbuildrc for DEB_BUILD_MAINT_OPTIONS to go through: $environment_filter = [Dpkg::BuildInfo::get_build_env_allowed(), 'DEB_BUILD_MAINT_OPTIONS']; Alternatively, one can also just take the easy route and pass hardening=-branch in DEB_BUILD_OPTIONS, which is whitelisted by default: DEB_BUILD_OPTIONS='nolang=m2 hardening=-branch' sbuild --host=arm64