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.
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.