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

Installed-only encryption provider makes encrypted-redo startup lose InnoDB

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 12.3.3
    • None
    • Encryption
    • None

    Description

      I can reproduce the encryption-provider form of MDEV-26800 in the official
      MariaDB 12.3.3 image.

      After `file_key_management` has been installed into `mysql.plugin`, restarting
      with `innodb_encrypt_log=ON` fails before InnoDB becomes available. Loading the
      same provider explicitly with `plugin_load_add=file_key_management.so` is a
      successful control. The installed-only startup exits because InnoDB checks for
      the encryption provider before the later `mysql.plugin` loading phase.

      Steps to reproduce

      The same temporary datadir is used for installation, the explicit-load
      control, and the installed-only trigger.

      set -eu
      IMAGE='mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979'
      C='mdev-installed-key-provider'
      OWNER="edbf-report-mcfg01-$$"
      D=$(mktemp -d)
      DATA="$D/data"
      mkdir "$DATA"
      chmod 0777 "$D" "$DATA"
      printf '%s\n' \
        '1;00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF' \
        >"$D/keys.txt"
      chmod 0444 "$D/keys.txt"
       
      owned_remove() {
        if docker inspect --format '{{ index .Config.Labels "io.encryptiondbfuzz.owner" }}' \
             "$C" 2>/dev/null | grep -Fqx "$OWNER"; then
          docker stop --time 20 "$C" >/dev/null 2>&1 || true
          docker rm -f "$C" >/dev/null 2>&1 || true
        fi
      }
      cleanup() {
        owned_remove
        rm -r "$D" >/dev/null 2>&1 || true
      }
      trap cleanup EXIT
       
      start_server() {
        docker run --detach --name "$C" \
          --label "io.encryptiondbfuzz.owner=$OWNER" \
          --network none --read-only --cap-drop ALL \
          --security-opt no-new-privileges=true --pids-limit 160 \
          --memory 1g --cpus 1 --user 999:999 \
          --mount type=bind,src="$DATA",dst=/var/lib/mysql \
          --mount type=bind,src="$D/keys.txt",dst=/edbf/keys.txt,readonly \
          --tmpfs /run/mysqld:rw,nosuid,nodev,size=16m,uid=999,gid=999 \
          --tmpfs /tmp:rw,nosuid,nodev,size=64m,uid=999,gid=999 \
          --env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 \
          "$IMAGE" "$@"
      }
       
      wait_ready() {
        READY=0
        for I in $(seq 1 90); do
          if docker exec --user 999:999 "$C" mariadb --protocol=socket \
               --socket=/run/mysqld/mysqld.sock -uroot -NBe 'SELECT @@port' \
               2>/dev/null | grep -qx 3306; then
            READY=1
            break
          fi
          sleep 1
        done
        test "$READY" -eq 1
      }
       
      # Install the provider into mysql.plugin, then stop this server.
      start_server --loose-file-key-management-filename=/edbf/keys.txt
      wait_ready
      docker exec --user 999:999 "$C" mariadb --protocol=socket \
        --socket=/run/mysqld/mysqld.sock -uroot -NBe \
        "INSTALL SONAME 'file_key_management';
         SELECT PLUGIN_NAME,PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS
         WHERE PLUGIN_NAME='file_key_management'"
      owned_remove
       
      # Control: explicit startup loading succeeds with encrypted redo enabled.
      start_server \
        --plugin-load-add=file_key_management.so \
        --loose-file-key-management-filename=/edbf/keys.txt \
        --innodb-encrypt-log=ON
      wait_ready
      docker exec --user 999:999 "$C" mariadb --protocol=socket \
        --socket=/run/mysqld/mysqld.sock -uroot -NBe \
        "SELECT SUPPORT FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE='InnoDB';
         SELECT PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS
         WHERE PLUGIN_NAME='file_key_management'"
      echo 'explicit_plugin_load_control=healthy'
      owned_remove
       
      # Trigger: rely only on the already installed mysql.plugin row.
      start_server \
        --loose-file-key-management-filename=/edbf/keys.txt \
        --innodb-encrypt-log=ON
      timeout 90 docker wait "$C" >/dev/null
      echo "installed_only_exit_code=$(docker inspect --format '{{.State.ExitCode}}' "$C")"
      docker logs "$C" 2>&1 | grep -E \
        'encryption plugin is not available|Plugin .InnoDB. registration|Unknown/unsupported storage engine|Aborting'
      

      Actual result

      The installation step reported `file_key_management ACTIVE`. The explicit
      startup-load control became ready and reported:

      DEFAULT
      ACTIVE
      explicit_plugin_load_control=healthy
      

      The installed-only trigger never became ready and exited 1:

      installed_only_exit_code=1
      InnoDB: cannot enable encryption, encryption plugin is not available
      Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
      Unknown/unsupported storage engine: InnoDB
      Aborting
      

      Expected result

      An encryption provider already installed in `mysql.plugin` should be available
      before InnoDB validates `innodb_encrypt_log=ON`, or InnoDB should defer/retry
      initialization until the provider-loading phase completes. The server should
      start just as it does with the equivalent explicit `plugin_load_add` control.

      Attachments

        Activity

          People

            shipjain Shipra Jain
            csfuzz csfuzz
            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.