Details
-
Bug
-
Status: Confirmed (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 13.0, 12.3.3
-
None
-
Linux x86_64; official image
`mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979`;
server reports `12.3.3-MariaDB-ubu2404`, source revision
`83e909fc2a0dbc394b4b683fb3fa2d7dcf26cc5e`.
Description
At startup, the Server Audit plugin accepts a long existing directory through
`server_audit_file_path`. The startup option path does not apply the length
check used by the dynamic variable update. `start_logging()` then appends the
default file name in a fixed stack buffer.
With a 981-byte existing directory, the official 12.3.3 `mariadbd` aborts with
glibc's buffer-overflow detector and signal 6. A short directory using the same
plugin and options starts normally and creates `server_audit.log`.
Steps to reproduce
Run on a disposable Docker host. The script creates only temporary synthetic
directories. It runs a short-path control first and then the long-path trigger.
set -eu
|
IMAGE='mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979'
|
CONTROL='mdev-audit-path-control'
|
TRIGGER='mdev-audit-path-trigger'
|
OWNER="edbf-report-mcfg07-$$"
|
D=$(mktemp -d)
|
|
|
owned_remove() {
|
NAME=$1
|
if docker inspect --format '{{ index .Config.Labels "io.encryptiondbfuzz.owner" }}' \
|
"$NAME" 2>/dev/null | grep -Fqx "$OWNER"; then
|
docker rm -f "$NAME" >/dev/null 2>&1 || true
|
fi
|
}
|
cleanup() {
|
owned_remove "$CONTROL"
|
owned_remove "$TRIGGER"
|
rm -r "$D" >/dev/null 2>&1 || true
|
}
|
trap cleanup EXIT
|
|
|
chmod 0777 "$D"
|
mkdir "$D/control"
|
chmod 0777 "$D/control"
|
HOST_PATH=$D
|
CONTAINER_PATH=/edbf-audit
|
for I in 0 1 2 3 4; do
|
PAD=$(printf '%0190d' 0 | tr 0 a)
|
PART="p${I}_${PAD}"
|
HOST_PATH="$HOST_PATH/$PART"
|
CONTAINER_PATH="$CONTAINER_PATH/$PART"
|
mkdir "$HOST_PATH"
|
chmod 0777 "$HOST_PATH"
|
done
|
echo "trigger_path_length=${#CONTAINER_PATH}"
|
|
|
COMMON_ARGS="--plugin-load-add=server_audit.so --server-audit-logging=ON --server-audit-output-type=file"
|
|
|
# Control: same plugin and options, but a short existing directory.
|
docker run --detach --name "$CONTROL" \
|
--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 \
|
--mount type=bind,src="$D",dst=/edbf-audit \
|
--env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 \
|
"$IMAGE" $COMMON_ARGS --server-audit-file-path=/edbf-audit/control
|
|
|
READY=0
|
for I in $(seq 1 90); do
|
if docker exec --user 999:999 "$CONTROL" 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
|
docker exec --user 999:999 "$CONTROL" \
|
test -f /edbf-audit/control/server_audit.log
|
echo 'short_path_control=healthy'
|
owned_remove "$CONTROL"
|
|
|
# Trigger: the path exists and is 981 bytes long inside the container.
|
docker run --detach --name "$TRIGGER" \
|
--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 \
|
--mount type=bind,src="$D",dst=/edbf-audit \
|
--env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 \
|
"$IMAGE" $COMMON_ARGS --server-audit-file-path="$CONTAINER_PATH"
|
|
|
timeout 90 docker wait "$TRIGGER" >/dev/null
|
echo "trigger_exit_code=$(docker inspect --format '{{.State.ExitCode}}' "$TRIGGER")"
|
echo "trigger_oom_killed=$(docker inspect --format '{{.State.OOMKilled}}' "$TRIGGER")"
|
docker logs "$TRIGGER" 2>&1 | grep -E \
|
'buffer overflow detected|got signal 6|server_audit\.so|initialize_audit_plugin|plugin_init'
|
Actual result
The short-path control became ready and created its audit file:
short_path_control=healthy
|
The trigger container was not OOM-killed. `mariadbd` exited 1 and its error log
contained:
trigger_path_length=981
|
trigger_exit_code=1
|
trigger_oom_killed=false
|
*** buffer overflow detected ***: terminated
|
/usr/sbin/mariadbd got signal 6 ;
|
server_audit.so(+0x3912)
|
server_audit.so(+0x79c5)
|
initialize_audit_plugin
|
plugin_init
|
mysqld_main
|
Expected result
Startup must validate `server_audit_file_path` before copying or appending to a
fixed buffer. An overlong value should produce a bounded configuration error;
it must not overwrite the stack or terminate `mariadbd`.
Attachments
Issue Links
- relates to
-
MDEV-36245 Long server_audit_file_path causes buffer overflow
-
- Closed
-