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

HandlerSocket silently remains ACTIVE after its configured listener fails to bind

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Minor
    • Resolution: Unresolved
    • 12.3.3
    • 10.11, 11.4, 11.8, 12.3
    • Plugins
    • None

    Description

      HandlerSocket installation succeeds and `INFORMATION_SCHEMA.PLUGINS` reports
      the plugin as `ACTIVE` even when its configured TCP listener cannot bind. The
      control below shows that an unused port gains a listener. The trigger assigns
      HandlerSocket the existing MariaDB listener address and port; installation
      still succeeds, but no HandlerSocket endpoint is created.

      Steps to reproduce

      set -eu
      IMAGE='mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979'
      C=''
      OWNER="edbf-report-mfu05-$$"
      cleanup() {
        if [ -n "$C" ] &&
           docker inspect --format '{{ index .Config.Labels "io.encryptiondbfuzz.owner" }}' \
             "$C" 2>/dev/null | grep -Fqx "$OWNER"; then
          docker rm -f "$C" >/dev/null 2>&1 || true
        fi
      }
      trap cleanup EXIT
       
      listen_count() {
        PORT=$1
        SUFFIX=$(printf ':%04X' "$PORT")
        docker exec --user 999:999 "$C" awk -v suffix="$SUFFIX" \
          '$4 == "0A" && substr($2, length($2)-4) == suffix { n++ }
           END { print n+0 }' /proc/net/tcp
      }
       
      run_case() {
        LABEL=$1
        PORT=$2
        C="mdev-mfu05-${LABEL}-$$"
        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 \
          --tmpfs /var/lib/mysql:rw,nosuid,nodev,size=512m,uid=999,gid=999 \
          --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" \
          --plugin-maturity=beta \
          --bind-address=127.0.0.1 \
          --loose-handlersocket-address=127.0.0.1 \
          --loose-handlersocket-port="$PORT" \
          --loose-handlersocket-port-wr=0 >/dev/null
       
        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
       
        echo "$LABEL before=$(listen_count "$PORT")"
        docker exec --user 999:999 "$C" mariadb --protocol=socket \
          --socket=/run/mysqld/mysqld.sock -uroot --batch --skip-column-names \
          -e "INSTALL SONAME 'handlersocket';
              SELECT PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS
              WHERE PLUGIN_NAME='handlersocket'"
        sleep 1
        echo "$LABEL after=$(listen_count "$PORT")"
        cleanup
        C=''
      }
       
      # Positive control: port 9998 is initially unused and becomes a listener.
      run_case unused_port 9998
       
      # Trigger: mariadbd already owns 127.0.0.1:3306.
      run_case occupied_port 3306
      

      Actual result

      unused_port before=0
      ACTIVE
      unused_port after=1
      occupied_port before=1
      ACTIVE
      occupied_port after=1
      

      The control adds one listener. In the trigger, the only listener after
      installation is still the original MariaDB socket, yet `INSTALL SONAME`
      returns success and the plugin reports `ACTIVE`.

      Expected result

      If the configured HandlerSocket endpoint cannot bind, plugin initialization
      should fail and `INSTALL SONAME` should return the listener error. The plugin
      must not report `ACTIVE` when its requested service endpoint is absent.

      Impact and boundary

      An administrator can receive a false-success result while the configured
      HandlerSocket service is unavailable. This can hide deployment failures and
      leave dependent applications without their expected endpoint. No crash,
      privilege bypass, or remote trigger was observed. Only 12.3.3 was tested. This
      report is researcher-reproduced and not yet maintainer-confirmed.

      Implementation observation

      `hstcpsvr::start_listen()` returns the bind error as a string. The HandlerSocket
      plugin initializer calls `start_listen()` for its read and write servers but
      does not examine either return value, releases the plugin data, and returns 0.

      Attachments

        Issue Links

          Activity

            People

              serg Sergei Golubchik
              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.