1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-07-30 19:03:17 +03:00

Fix my_context_[spawn|continue|yield] for aarch64 BTI

Fixes SIGILL in MariaDB Server "main.non_blocking_api" test case on
aarch64 processors supporting Branch Target Identification (BTI).

Branch Target Identification is a new aarch64 feature that prevents
jumping to arbitrary code locations that are not properly marked as
branch targets.

The "-mbranch-protection=standard" flag to GCC will enable code
generation using BTI. This is backwards compatible as the added
instructions are no-ops on older processors.

One example of where both "-mbranch-protection=standard" is enabled and
hardware supports it is with Amazon Linux 2023 and Graviton 4.

The symptom is the following mtr main.non_blocking_api failure:

  mysqltest got signal 4
  read_command_buf (0xaaaae6ae27a8): connect
  (con_nonblock,localhost,root,,test)

  conn->name (0xaaaae6b0c0b8):

  Attempting backtrace...
  stack_bottom = 0x0 thread_stack 0x3c000
  /usr/bin/mariadb-test(my_print_stacktrace+0x48)[0xaaaab6934088]
  bits/stdio2.h:79(signal_handler)[0xaaaab68f41a0]
  addr2line: 'linux-vdso.so.1': No such file
  linux-vdso.so.1(__kernel_rt_sigreturn+0x0)[0xffffa22bc830]
  /usr/bin/mariadb-test(my_context_spawn+0x74)[0xaaaab6914d84]

With GDB giving the information that SIGILL was on the perfectly legal
'mov' instruction:

  Program received signal SIGILL, Illegal instruction.
  0x0000aaaaaab44d84 in my_context_spawn (c=0xaaaaab07ada8, f=0xfffff7fed240, d=0x0) at
  mariadb1011-10.11.11-1.amzn2023.0.1.aarch64/libmariadb/libmariadb/ma_context.c:674
  674       __asm__ __volatile__
  (gdb) x/i$pc
  => 0xaaaaaab44d84 <my_context_spawn(my_context*, void (*)(void*),
  void*)+116>: mov      w0, #0x1                        // #1

The call sequence to get to this point is as follows:

  Breakpoint 1, my_context_spawn (c=0xaaaaab07ada8, f=0xaaaaaab38024
  <mysql_real_connect_start_internal(void*)>, d=0xffffffffc648) at
  libmariadb/ma_context.c:661
  661       register void *stack asm("x13") = c->stack_top;
  (gdb) c
  Continuing.

  Breakpoint 2, my_context_yield (c=0xaaaaab07ada8) at
  libmariadb/ma_context.c:843
  843       register const uint64_t *save asm("x19") = &c->save[0];

  Continuing from here leads to the SIGILL above.

The branch that ends up causing the SIGILL is the "br x11" instruction
in my_context_yield(). This is due to the branch being to a location
that is not marked as a branch target.

The fix is to ensure that these locations in the my_context aarch64
assembler are marked with "bti j" instructions so that the locations
that will be 'br'ed to are valid to be 'br'ed to.

Since older compilers don't know about the instruction, we need an ifdef
to define a string that has the raw opcode in it.

Fixes: d2285fb830
This commit is contained in:
Stewart Smith
2025-05-13 13:52:41 -07:00
parent c07e50d940
commit e2e5113a53

View File

@ -637,6 +637,13 @@ my_context_destroy(struct my_context *c)
#ifdef MY_CONTEXT_USE_AARCH64_GCC_ASM
#if (defined(__clang__) && (__clang_major__ >= 9)) || \
(defined(__GNUC__) && (__GNUC__ > 9 || (__GNUC__ == 9 && __GNUC_MINOR__ >= 1)))
#define BTI_J_STR "bti j"
#else
#define BTI_J_STR ".inst 0xd503241f"
#endif
/*
GCC-aarch64 (arm64) implementation of my_context.
@ -724,12 +731,14 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
will do this for us if needed.
*/
"1:\n\t"
BTI_J_STR "\n\t"
"ldr x10, [%[save], #88]\n\t"
"mov sp, x10\n\t"
"mov %w[ret], #0\n\t"
"b 3f\n"
/* Come here when operation was suspended. */
"2:\n\t"
BTI_J_STR "\n\t"
"mov %w[ret], #1\n"
"3:\n"
: [ret] "=r" (ret),
@ -824,6 +833,7 @@ my_context_continue(struct my_context *c)
my_context_spawn(), so we preserve the value correctly at this point.
*/
"1:\n\t"
BTI_J_STR "\n\t"
/* x19 (aka %[save]) is preserved from my_context_spawn() in this case. */
"ldr x20, [%[save], #8]\n\t"
"ldp x21, x22, [%[save], #16]\n\t"
@ -840,6 +850,7 @@ my_context_continue(struct my_context *c)
"b 3f\n"
/* Come here when operation is suspended. */
"2:\n\t"
BTI_J_STR "\n\t"
"mov %w[ret], #1\n"
"3:\n"
: [ret] "=r" (ret)
@ -923,6 +934,7 @@ my_context_yield(struct my_context *c)
"br x11\n"
"1:\n"
BTI_J_STR "\n\t"
:
: [save] "r" (save)
: "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",