Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-42096

BSD ARM64 CRC capability detection passes a one-byte buffer length and selects software fallbacks

    XMLWordPrintable

Details

    • Bug
    • Status: Confirmed (View Workflow)
    • Minor
    • Resolution: Unresolved
    • 10.11, 11.4, 11.8, 12.3, 13.1, 12.3.3
    • 10.11, 11.4, 11.8, 12.3, 13.1
    • None
    • None
    • Source-contract harness run on Linux/amd64 with a POSIX shell and C11 compiler; native BSD ARM64 execution was not performed.

    Description

      MariaDB 12.3.3 source contains an incorrect elf_aux_info() call in the FreeBSD/OpenBSD ARM64 CRC capability adapter. The adapter passes the result of (int)sizeof(val) != 0, which is 1, as the output-buffer length. A strict ABI harness therefore rejects the capability query, and both CRC32 and CRC32C dispatch select their software fallbacks.

      This occurs when a FreeBSD or OpenBSD ARM64 build has HAVE_ARMV8_CRC enabled and hardware CRC capability is available.

      Source-contract reproducer

      Save the following three files in one directory. The harness requires a POSIX shell, a C11 compiler, and an unsigned long wider than one byte.

      target_probe.inc contains the relevant adapter and availability function from the tested source:

      static unsigned long getauxval(unsigned int key)
      {
        unsigned long val;
        if (elf_aux_info(key, (void *)&val, (int)sizeof(val) != 0))
          return 0ul;
        return val;
      }
       
      int crc32_aarch64_available(void)
      {
        unsigned long auxv= getauxval(AT_HWCAP);
        return (auxv & HWCAP_CRC32) != 0;
      }

      Save this as probe.c:

      #include <stdio.h>
      #include <errno.h>
      #define AT_HWCAP 25U
      #define HWCAP_CRC32 (1UL << 7)
      static int observed_length;
      /* Contract model, not the BSD implementation. */
      static int elf_aux_info(unsigned int key, void *buffer, int length)
      {
        observed_length = length;
        if (key != AT_HWCAP || length != (int)sizeof(unsigned long))
          return EINVAL;
        *(unsigned long *)buffer = HWCAP_CRC32;
        return 0;
      }
      #include "target_probe.inc"
      static unsigned long control_getauxval(unsigned int key)
      {
        unsigned long val;
        if (elf_aux_info(key, (void *)&val, (int)sizeof(val)) != 0)
          return 0ul;
        return val;
      }
      int main(void)
      {
        int available = crc32_aarch64_available();
        int target_length = observed_length;
        int control_available = (control_getauxval(AT_HWCAP) & HWCAP_CRC32) != 0;
        printf("target: length=%d expected=%zu available=%d\n",
               target_length, sizeof(unsigned long), available);
        printf("control: length=%d expected=%zu available=%d\n",
               observed_length, sizeof(unsigned long), control_available);
        if (sizeof(unsigned long) > 1 && target_length == 1 && !available &&
            observed_length == (int)sizeof(unsigned long) && control_available)
        {
          puts("ORACLE=ADAPTER_LENGTH_DEFECT");
          return 0;
        }
        puts("ORACLE=NOT_REPRODUCED");
        return 1;
      }

      Save this as run.sh:

      #!/bin/sh
      set -eu
      cd "$(dirname "$0")"
      "${CC:-cc}" -std=c11 -Wall -Wextra -Werror probe.c -o probe
      ./probe

      Run:

      sh run.sh

      The recorded output was:

      target: length=1 expected=8 available=0
      control: length=8 expected=8 available=1
      ORACLE=ADAPTER_LENGTH_DEFECT
      exit_status=0

      The target call supplies length 1, so the modeled elf_aux_info() contract rejects it and CRC32 capability appears unavailable. The control passes sizeof(val) and detects the same modeled capability with length 8. MariaDB's build probes likewise pass the full size of an unsigned long to elf_aux_info().

      The adapter should pass the full output-buffer size to elf_aux_info() and test the function's return value separately. Both CRC availability functions consume this adapter; a rejected query makes CRC32 and CRC32C dispatch choose software implementations. The evidence establishes no incorrect checksum, data corruption, or measured performance impact. It validates the source-level ABI interaction rather than native FreeBSD/OpenBSD server execution.

      Attachments

        Activity

          People

            gkodinov Georgi Kodinov
            imchifan 刘启帆
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.