Commit 314bcbf0 authored by Mark Brown's avatar Mark Brown Committed by Catalin Marinas
Browse files

kselftest: arm64: Add BTI tests



Add some tests that verify that BTI functions correctly for static binaries
built with and without BTI support, verifying that SIGILL is generated when
expected and is not generated in other situations.

Since BTI support is still being rolled out in distributions these tests
are built entirely free standing, no libc support is used at all so none
of the standard helper functions for kselftest can be used and we open
code everything. This also means we aren't testing the kernel support for
the dynamic linker, though the test program can be readily adapted for
that once it becomes something that we can reliably build and run.

These tests were originally written by Dave Martin, I've adapted them for
kselftest, mainly around the build system and the output format.

Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Link: https://lore.kernel.org/r/20210309193731.57247-1-broonie@kernel.org


Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 75347add
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
ARCH ?= $(shell uname -m 2>/dev/null || echo not)

ifneq (,$(filter $(ARCH),aarch64 arm64))
ARM64_SUBTARGETS ?= tags signal pauth fp mte
ARM64_SUBTARGETS ?= tags signal pauth fp mte bti
else
ARM64_SUBTARGETS :=
endif
+2 −0
Original line number Diff line number Diff line
btitest
nobtitest
+61 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0

TEST_GEN_PROGS := btitest nobtitest

PROGS := $(patsubst %,gen/%,$(TEST_GEN_PROGS))

# These tests are built as freestanding binaries since otherwise BTI
# support in ld.so is required which is not currently widespread; when
# it is available it will still be useful to test this separately as the
# cases for statically linked and dynamically lined binaries are
# slightly different.

CFLAGS_NOBTI = -DBTI=0
CFLAGS_BTI = -mbranch-protection=standard -DBTI=1

CFLAGS_COMMON = -ffreestanding -Wall -Wextra $(CFLAGS)

BTI_CC_COMMAND = $(CC) $(CFLAGS_BTI) $(CFLAGS_COMMON) -c -o $@ $<
NOBTI_CC_COMMAND = $(CC) $(CFLAGS_NOBTI) $(CFLAGS_COMMON) -c -o $@ $<

%-bti.o: %.c
	$(BTI_CC_COMMAND)

%-bti.o: %.S
	$(BTI_CC_COMMAND)

%-nobti.o: %.c
	$(NOBTI_CC_COMMAND)

%-nobti.o: %.S
	$(NOBTI_CC_COMMAND)

BTI_OBJS =                                      \
	test-bti.o                           \
	signal-bti.o                            \
	start-bti.o                             \
	syscall-bti.o                           \
	system-bti.o                            \
	teststubs-bti.o                         \
	trampoline-bti.o
gen/btitest: $(BTI_OBJS)
	$(CC) $(CFLAGS_BTI) $(CFLAGS_COMMON) -nostdlib -o $@ $^

NOBTI_OBJS =                                    \
	test-nobti.o                         \
	signal-nobti.o                          \
	start-nobti.o                           \
	syscall-nobti.o                         \
	system-nobti.o                          \
	teststubs-nobti.o                       \
	trampoline-nobti.o
gen/nobtitest: $(NOBTI_OBJS)
	$(CC) $(CFLAGS_BTI) $(CFLAGS_COMMON) -nostdlib -o $@ $^

# Including KSFT lib.mk here will also mangle the TEST_GEN_PROGS list
# to account for any OUTPUT target-dirs optionally provided by
# the toplevel makefile
include ../../lib.mk

$(TEST_GEN_PROGS): $(PROGS)
	cp $(PROGS) $(OUTPUT)/
+80 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2019  Arm Limited
 * Original author: Dave Martin <Dave.Martin@arm.com>
 */

#ifndef ASSEMBLER_H
#define ASSEMBLER_H

#define NT_GNU_PROPERTY_TYPE_0	5
#define GNU_PROPERTY_AARCH64_FEATURE_1_AND	0xc0000000

/* Bits for GNU_PROPERTY_AARCH64_FEATURE_1_BTI */
#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI	(1U << 0)
#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC	(1U << 1)


.macro startfn name:req
	.globl \name
\name:
	.macro endfn
		.size \name, . - \name
		.type \name, @function
		.purgem endfn
	.endm
.endm

.macro emit_aarch64_feature_1_and
	.pushsection .note.gnu.property, "a"
	.align	3
	.long	2f - 1f
	.long	6f - 3f
	.long	NT_GNU_PROPERTY_TYPE_0
1:	.string	"GNU"
2:
	.align	3
3:	.long	GNU_PROPERTY_AARCH64_FEATURE_1_AND
	.long	5f - 4f
4:
#if BTI
	.long	GNU_PROPERTY_AARCH64_FEATURE_1_PAC | \
		GNU_PROPERTY_AARCH64_FEATURE_1_BTI
#else
	.long	0
#endif
5:
	.align	3
6:
	.popsection
.endm

.macro paciasp
	hint	0x19
.endm

.macro autiasp
	hint	0x1d
.endm

.macro __bti_
	hint	0x20
.endm

.macro __bti_c
	hint	0x22
.endm

.macro __bti_j
	hint	0x24
.endm

.macro __bti_jc
	hint	0x26
.endm

.macro bti what=
	__bti_\what
.endm

#endif /* ! ASSEMBLER_H */
+23 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2019  Arm Limited
 * Original author: Dave Martin <Dave.Martin@arm.com>
 */

#ifndef BTITEST_H
#define BTITEST_H

/* Trampolines for calling the test stubs: */
void call_using_br_x0(void (*)(void));
void call_using_br_x16(void (*)(void));
void call_using_blr(void (*)(void));

/* Test stubs: */
void nohint_func(void);
void bti_none_func(void);
void bti_c_func(void);
void bti_j_func(void);
void bti_jc_func(void);
void paciasp_func(void);

#endif /* !BTITEST_H */
Loading