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

SUBSTR with INT32_MIN position triggers signed-overflow UBSAN in Item_func_substr

    XMLWordPrintable

Details

    Description

      1. MariaDB `SUBSTR` signed overflow for `INT32_MIN` position

      Status: reproduced on MariaDB current main SHA `9d7ab2c0092df4bc73b64b915464aecf7e5fe6c4` (13.2.0 development tree).

        1. Reproduction environment
      • Linux x86_64
      • Clang 14
      • Debug build with AddressSanitizer and UndefinedBehaviorSanitizer
      • `WITH_UNIT_TESTS=OFF`, `WITH_WSREP=OFF`
        1. Minimal reproducer

      ```sql
      SELECT SUBSTR('a', -2147483648);
      ```

      `SUBSTRING` is equivalent and reaches the same path. No table, data, transaction state, special SQL mode, or elevated privilege is required.

        1. Observed result

      UBSan reports:

      ```text
      sql/item_strfunc.cc:2005:27: runtime error:
      negation of -2147483648 cannot be represented in type 'int32' (aka 'int')
      ```

      With UBSan recovery enabled, the query returns the empty result and the server remains usable. With `UBSAN_OPTIONS=halt_on_error=1`, the client loses the connection and the server exits with status 1. A non-sanitized Debug build returns the empty result and remains alive.

        1. Expected result

      The out-of-range negative position should produce the empty result without invoking undefined behavior.

        1. Root cause

      `Item_func_substr::fix_length_and_dec()` narrows the constant position to `int32`. When the value is negative, it evaluates `(uint)(-start)`. Negating `INT32_MIN` is not representable in signed `int32`, so the expression has undefined behavior before the unsigned cast.

      The same unguarded negation remains in current main at the tested SHA.

        1. Impact

      This is SQL-reachable signed-overflow UB and a correctness/hardening defect. No ordinary-release crash, memory corruption, privilege-boundary impact, or security exploitability has been demonstrated.

        1. Duplicate audit

      No exact public duplicate was found. MDEV-37012 reaches the same fixup method through an out-of-range user-variable-to-`long long` conversion. MDEV-28387/MDEV-31221 concern `LLONG_MIN` parsing in `my_strtoll10`. Neither covers the `int32 -start` operation here.

        1. Discovery

      Found by DBMS-StateFuzz and reduced from a stateful typed query to the scalar statement above.

      Credit: Zheng Wang, Yanjie Zhao, and Yiyang Liu.

      Attachments

        Issue Links

          Activity

            People

              bar Alexander Barkov
              hacker_zheng Wang Zheng
              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.