Bug #121604 START GROUP_REPLICATION with a long ssl_cipher overflows the XCOM SSL cipher stack buffer
Submitted: 25 Oct 15:12
Reporter: Wwwwing Wwwwing Email Updates:
Status: Open Impact on me:
None 
Category:MySQL Server: Group Replication Severity:S3 (Non-critical)
Version:MySQL 8.4.11 official image OS:Any
Assigned to: CPU Architecture:Any

[25 Oct 15:12] Wwwwing Wwwwing
Description:
`group_replication_ssl_mode=REQUIRED` makes the XCOM network provider build a
TLS cipher configuration from the global `ssl_cipher` value. In
`xcom_network_provider_ssl_native_lib.cc::configure_ssl_algorithms()` the blocked
cipher list and the configured cipher list are concatenated into a fixed
`char cipher_list[4096]` stack buffer, but both `strncat` calls use
`SSL_CIPHER_LIST_SIZE - 1` as the maximum append length instead of the remaining
capacity. With a cipher string of 3902 bytes or more (the blocked prefix is
194 bytes), the second append writes past the end of the stack buffer.

`ssl_cipher` itself imposes no length limit: `check_tls12_ciphers` only rejects
tokens that do not start with `!` and are absent from the default list, so a
string consisting of `!` plus arbitrary characters is accepted.

How to repeat:
```bash
IMG=mysql@sha256:85b9bf2e29cf836ecb8c2a15a935d4ba0c606631dff1dd79531a11983c638f2a
DATA=$(mktemp -d); chown 999:999 "$DATA"
docker run -d --name my66 --network none --read-only --cap-drop ALL \
  --security-opt no-new-privileges=true --pids-limit 512 --memory 2048m --cpus 2 \
  --user 999:999 --mount type=bind,src="$DATA",dst=/var/lib/mysql \
  --tmpfs /var/run/mysqld:rw,noexec,nosuid,nodev,size=16m,uid=999,gid=999 \
  -e MYSQL_ALLOW_EMPTY_PASSWORD=yes "$IMG" \
  --skip-name-resolve --log-error=/var/lib/mysql/error.log --log-error-verbosity=3 \
  --server-id=1 --log-bin=mysql-bin --gtid-mode=ON \
  --enforce-gtid-consistency=ON --log-replica-updates=ON --binlog-format=ROW

# wait until ready
docker exec my66 mysql -uroot --socket=/var/run/mysqld/mysqld.sock -e \
  "INSTALL PLUGIN group_replication SONAME 'group_replication.so';
   SET GLOBAL group_replication_group_name='aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';
   SET GLOBAL group_replication_local_address='127.0.0.1:33061';
   SET GLOBAL group_replication_bootstrap_group=ON;
   SET GLOBAL group_replication_ssl_mode='REQUIRED';"

# control (no long cipher): START GROUP_REPLICATION returns 0, no crash
docker exec my66 mysql -uroot --socket=/var/run/mysqld/mysqld.sock -e \
  "START GROUP_REPLICATION;"
# restart the container for a clean fault run, then set the long cipher:
python3 -c "print('!' + 'A'*4000)" > "$WORK/cipher.txt"
docker exec my66 mysql -uroot --socket=/var/run/mysqld/mysqld.sock -e \
  "SET GLOBAL ssl_cipher='$(cat "$WORK/cipher.txt")';"
docker exec my66 mysql -uroot --socket=/var/run/mysqld/mysqld.sock -e \
  "START GROUP_REPLICATION;"
sleep 5
docker inspect -f '{{.State.Running}} {{.State.ExitCode}}' my66
grep -a -E "buffer overflow detected|got signal 6" "$DATA/error.log"
```

## Actual result

Control run: `START GROUP_REPLICATION` returns 0 and the log records
`Group communication SSL configuration: ... cipher: "..."` with no crash.

Fault run with a 4001-byte `ssl_cipher` value:

```text
*** buffer overflow detected ***: terminated
2026-10-23T07:33:40Z UTC - mysqld got signal 6 ;
```

The container exits and the server must be restarted. glibc fortified
`strncat` detects the write past the 4096-byte stack buffer; the overflow can
reach roughly 195 bytes beyond the buffer and consists of printable bytes from
the configured cipher string.

## Expected result

The cipher concatenation should be bounded by the remaining buffer capacity (or
use `std::string`), and `ssl_cipher` should reject absurdly long values or fail
cleanly with an error instead of aborting the server.