[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v6 6/6] tests/tcg/aarch64: Add bti smoke test
From: |
Dave Martin |
Subject: |
Re: [Qemu-devel] [PATCH v6 6/6] tests/tcg/aarch64: Add bti smoke test |
Date: |
Thu, 6 Jun 2019 11:21:41 +0100 |
User-agent: |
Mutt/1.5.23 (2014-03-12) |
On Wed, Jun 05, 2019 at 09:57:06PM +0100, Richard Henderson wrote:
> This will build with older toolchains, without the upstream support
> for -mbranch-protection. Such a toolchain will produce a warning
> in such cases,
>
> ld: warning: /tmp/ccyZt0kq.o: unsupported GNU_PROPERTY_TYPE (5) \
> type: 0xc0000000
>
> but the still places the note at the correct location in the binary
> for processing by the runtime loader.
>
> Signed-off-by: Richard Henderson <address@hidden>
> ---
> tests/tcg/aarch64/bti-1.c | 77 +++++++++++++++++++++++++++++++
> tests/tcg/aarch64/bti-crt.inc.c | 69 +++++++++++++++++++++++++++
> tests/tcg/aarch64/Makefile.target | 3 ++
> 3 files changed, 149 insertions(+)
> create mode 100644 tests/tcg/aarch64/bti-1.c
> create mode 100644 tests/tcg/aarch64/bti-crt.inc.c
>
> diff --git a/tests/tcg/aarch64/bti-1.c b/tests/tcg/aarch64/bti-1.c
> new file mode 100644
> index 0000000000..2aee57ea7a
> --- /dev/null
> +++ b/tests/tcg/aarch64/bti-1.c
> @@ -0,0 +1,77 @@
> +/*
> + * Branch target identification, basic notskip cases.
> + */
> +
> +#include "bti-crt.inc.c"
> +
> +/*
> + * Work around lack of -mbranch-protection=standard in older toolchains.
> + * The signal handler is invoked by the kernel with PSTATE.BTYPE=2, which
> + * means that the handler must begin with a marker like BTI_C.
> + */
> +asm("skip2_sigill1:\n\
> + hint #34\n\
> + b skip2_sigill2\n\
> +.type skip2_sigill1,%function\n\
> +.size skip2_sigill1,8");
> +
> +extern void skip2_sigill1(int sig, siginfo_t *info, ucontext_t *uc)
> + __attribute__((visibility("hidden")));
> +
> +static void __attribute__((used))
> +skip2_sigill2(int sig, siginfo_t *info, ucontext_t *uc)
> +{
> + uc->uc_mcontext.pc += 8;
> + uc->uc_mcontext.pstate = 1;
> +}
> +
> +#define NOP "nop"
> +#define BTI_N "hint #32"
> +#define BTI_C "hint #34"
> +#define BTI_J "hint #36"
> +#define BTI_JC "hint #38"
> +
> +#define BTYPE_1(DEST) \
> + asm("mov %0,#1; adr x16, 1f; br x16; 1: " DEST "; mov %0,#0" \
> + : "=r"(skipped) : : "x16")
> +
> +#define BTYPE_2(DEST) \
> + asm("mov %0,#1; adr x16, 1f; blr x16; 1: " DEST "; mov %0,#0" \
> + : "=r"(skipped) : : "x16", "x30")
> +
> +#define BTYPE_3(DEST) \
> + asm("mov %0,#1; adr x15, 1f; br x15; 1: " DEST "; mov %0,#0" \
> + : "=r"(skipped) : : "x15")
> +
> +#define TEST(WHICH, DEST, EXPECT) \
> + do { WHICH(DEST); fail += skipped ^ EXPECT; } while (0)
> +
> +
> +int main()
> +{
> + int fail = 0;
> + int skipped;
> +
> + /* Signal-like with SA_SIGINFO. */
> + signal_info(SIGILL, skip2_sigill1);
> +
> + TEST(BTYPE_1, NOP, 1);
> + TEST(BTYPE_1, BTI_N, 1);
> + TEST(BTYPE_1, BTI_C, 0);
> + TEST(BTYPE_1, BTI_J, 0);
> + TEST(BTYPE_1, BTI_JC, 0);
> +
> + TEST(BTYPE_2, NOP, 1);
> + TEST(BTYPE_2, BTI_N, 1);
> + TEST(BTYPE_2, BTI_C, 0);
> + TEST(BTYPE_2, BTI_J, 1);
> + TEST(BTYPE_2, BTI_JC, 0);
> +
> + TEST(BTYPE_3, NOP, 1);
> + TEST(BTYPE_3, BTI_N, 1);
> + TEST(BTYPE_3, BTI_C, 1);
> + TEST(BTYPE_3, BTI_J, 0);
> + TEST(BTYPE_3, BTI_JC, 0);
> +
> + return fail;
> +}
> diff --git a/tests/tcg/aarch64/bti-crt.inc.c b/tests/tcg/aarch64/bti-crt.inc.c
> new file mode 100644
> index 0000000000..bb363853de
> --- /dev/null
> +++ b/tests/tcg/aarch64/bti-crt.inc.c
> @@ -0,0 +1,69 @@
> +/*
> + * Minimal user-environment for testing BTI.
> + *
> + * Normal libc is not built with BTI support enabled, and so could
> + * generate a BTI TRAP before ever reaching main.
> + */
> +
> +#include <stdlib.h>
> +#include <signal.h>
> +#include <ucontext.h>
> +#include <asm/unistd.h>
> +
> +int main(void);
> +
> +void _start(void)
> +{
> + exit(main());
> +}
> +
> +void exit(int ret)
> +{
> + register int x0 __asm__("x0") = ret;
> + register int x8 __asm__("x8") = __NR_exit;
> +
> + asm volatile("svc #0" : : "r"(x0), "r"(x8));
> + __builtin_unreachable();
> +}
> +
> +/*
> + * Irritatingly, the user API struct sigaction does not match the
> + * kernel API struct sigaction. So for simplicity, isolate the
> + * kernel ABI here, and make this act like signal.
> + */
> +void signal_info(int sig, void (*fn)(int, siginfo_t *, ucontext_t *))
> +{
> + struct kernel_sigaction {
> + void (*handler)(int, siginfo_t *, ucontext_t *);
> + unsigned long flags;
> + unsigned long restorer;
> + unsigned long mask;
> + } sa = { fn, SA_SIGINFO, 0, 0 };
> +
> + register int x0 __asm__("x0") = sig;
> + register void *x1 __asm__("x1") = &sa;
> + register void *x2 __asm__("x2") = 0;
> + register int x3 __asm__("x3") = sizeof(unsigned long);
> + register int x8 __asm__("x8") = __NR_rt_sigaction;
> +
> + asm volatile("svc #0"
> + : : "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x8) : "memory");
> +}
> +
> +/*
> + * Create the PT_NOTE that will enable BTI in the page tables.
> + * This will be created by the compiler with -mbranch-protection=standard,
> + * but as of 2019-03-29, this is has not been committed to gcc mainline.
> + * This will probably be in GCC10.
FYI, GCC9 has it.
> + */
> +asm(".section .note.gnu.property,\"a\"\n\
> + .align 3\n\
> + .long 4\n\
> + .long 16\n\
> + .long 5\n\
> + .string \"GNU\"\n\
> + .long 0xc0000000\n\
> + .long 4\n\
> + .long 1\n\
> + .align 3\n\
> + .previous");
Note, this won't be enough to generate the PT_GNU_PROPERTY entry in the
program header table using older tools.
This may be work-round-able with a linker script, but I haven't looked
into it.
> diff --git a/tests/tcg/aarch64/Makefile.target
> b/tests/tcg/aarch64/Makefile.target
> index 2bb914975b..21da3bc37f 100644
> --- a/tests/tcg/aarch64/Makefile.target
> +++ b/tests/tcg/aarch64/Makefile.target
> @@ -18,4 +18,7 @@ run-fcvt: fcvt
> AARCH64_TESTS += pauth-1
> run-pauth-%: QEMU += -cpu max
>
> +AARCH64_TESTS += bti-1
> +bti-1: LDFLAGS += -nostartfiles -nodefaultlibs -nostdlib
> +
Doesn't -nostdlib imply -nodefaultlibs and -nostartfiles?
Cheers
---Dave
- [Qemu-devel] [PATCH v6 3/6] linux-user: Set PAGE_TARGET_1 for TARGET_PROT_BTI, (continued)
- [Qemu-devel] [PATCH v6 3/6] linux-user: Set PAGE_TARGET_1 for TARGET_PROT_BTI, Richard Henderson, 2019/06/05
- [Qemu-devel] [PATCH v6 2/6] linux-user: Validate mmap/mprotect prot value, Richard Henderson, 2019/06/05
- [Qemu-devel] [PATCH v6 4/6] include/elf: Add defines related to notes for GNU systems, Richard Henderson, 2019/06/05
- [Qemu-devel] [PATCH v6 5/6] linux-user: Parse NT_GNU_PROPERTY_TYPE_0 notes, Richard Henderson, 2019/06/05
- [Qemu-devel] [PATCH v6 6/6] tests/tcg/aarch64: Add bti smoke test, Richard Henderson, 2019/06/05
- Re: [Qemu-devel] [PATCH v6 6/6] tests/tcg/aarch64: Add bti smoke test,
Dave Martin <=
- Re: [Qemu-devel] [PATCH v6 0/6] linux-user/aarch64: Support PROT_BTI, no-reply, 2019/06/05