From: Stefan Metzmacher Date: Fri, 17 Nov 2023 10:46:27 +0000 (+0100) Subject: s3:selftest: add samba3.blackbox.smbXsrv_client_ctdb_registered_ips X-Git-Tag: samba-4.18.10~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f8c02609f4807435cbdee1d1433429a549fc981e;p=thirdparty%2Fsamba.git s3:selftest: add samba3.blackbox.smbXsrv_client_ctdb_registered_ips This demonstrates the crash that happens if a client connects to a non-public address first followed by a connect to public address with the same client_guid and a connection to the non-public address gets disconnected first, we hit by a use-after-free talloc_get_type_abort() called from release_ip() as "xconn" is already gone, taking smbd_release_ip_state with it. Note that we also need to mark some subtests as flapping as there's a 2nd problem that happens in the interaction between smbd processes and ctdb when passing a multichannel connection to an existing process, it means we sometimes loose the 'tickle' information within ctdb to that tcp connection. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523 Signed-off-by: Stefan Metzmacher Reviewed-by: Martin Schwenke (cherry picked from commit 082c7df4d04c2a94c5413c1d6b7eae7be610f950) --- diff --git a/selftest/flapping.d/smbXsrv_client_ctdb_registered_ips b/selftest/flapping.d/smbXsrv_client_ctdb_registered_ips new file mode 100644 index 00000000000..740bb87251b --- /dev/null +++ b/selftest/flapping.d/smbXsrv_client_ctdb_registered_ips @@ -0,0 +1,4 @@ +^samba3.blackbox.smbXsrv_client_ctdb_registered_ips.step5:.ctdb_gettickles.NUM +^samba3.blackbox.smbXsrv_client_ctdb_registered_ips.step5:.ctdb_gettickles.DST +^samba3.blackbox.smbXsrv_client_ctdb_registered_ips.step6:.ctdb_gettickles.NUM +^samba3.blackbox.smbXsrv_client_ctdb_registered_ips.step6:.ctdb_gettickles.DST diff --git a/selftest/knownfail.d/smbXsrv_client_ctdb_registered_ips b/selftest/knownfail.d/smbXsrv_client_ctdb_registered_ips new file mode 100644 index 00000000000..8bce2bbb5db --- /dev/null +++ b/selftest/knownfail.d/smbXsrv_client_ctdb_registered_ips @@ -0,0 +1 @@ +^samba3.blackbox.smbXsrv_client_ctdb_registered_ips.step7:.smbstatus.0.sessions diff --git a/source3/script/tests/test_smbXsrv_client_ctdb_registered_ips.sh b/source3/script/tests/test_smbXsrv_client_ctdb_registered_ips.sh new file mode 100755 index 00000000000..025a0fa837c --- /dev/null +++ b/source3/script/tests/test_smbXsrv_client_ctdb_registered_ips.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash +# +# Test smbd let cleanup registered ip addresses in a multichannel +# scenario +# + +if [ $# -lt 3 ]; then + echo Usage: test_smbXsrv_client_ctdb_registered_ips.sh SERVERCONFFILE CTDB_IFACE_IP SHARENAME + exit 1 +fi + +CONF=$1 +CTDB_IFACE_IP=$2 +SHARE=$3 + +SMBCLIENT="$BINDIR/smbclient" +SMBSTATUS="$BINDIR/smbstatus" +CTDB="$BINDIR/ctdb" +TIMELIMIT="$BINDIR/timelimit" + +incdir=$(dirname "$0")/../../../testprogs/blackbox +. "$incdir"/subunit.sh + +failed=0 + +test_smbclient() +{ + name="$1" + server="$2" + share="$3" + cmd="$4" + shift + shift + subunit_start_test "$name" + output=$($VALGRIND $SMBCLIENT //$server/$share -c "$cmd" "$@" 2>&1) + status=$? + if [ x$status = x0 ]; then + subunit_pass_test "$name" + else + echo "$output" | subunit_fail_test "$name" + fi + return $status +} + +cd "$SELFTEST_TMPDIR" || exit 1 + +# Create the smbclient communication pipes. +rm -f smbclient1-stdin smbclient1-stdout smbclient1-stderr +mkfifo smbclient1-stdin smbclient1-stdout smbclient1-stderr +rm -f smbclient2-stdin smbclient2-stdout smbclient2-stderr +mkfifo smbclient2-stdin smbclient2-stdout smbclient2-stderr + +smbstatus_num_sessions() +{ + # We don't check for died processes + UID_WRAPPER_INITIAL_RUID=0 UID_WRAPPER_INITIAL_EUID=0 "$SMBSTATUS" "$CONF" --fast --json | jq -M '.sessions | length' +} + +ctdb_add_public_ip() +{ + UID_WRAPPER_INITIAL_RUID=0 UID_WRAPPER_INITIAL_EUID=0 "$CTDB" addip ${CTDB_IFACE_IP}/24 lo + UID_WRAPPER_INITIAL_RUID=0 UID_WRAPPER_INITIAL_EUID=0 "$CTDB" ipreallocate +} + +ctdb_ip() +{ + UID_WRAPPER_INITIAL_RUID=0 UID_WRAPPER_INITIAL_EUID=0 "$CTDB" ip +} + +ctdb_gettickles() +{ + UID_WRAPPER_INITIAL_RUID=0 UID_WRAPPER_INITIAL_EUID=0 "$CTDB" gettickles ${CTDB_IFACE_IP} +} + +ctdb_reload_public_ips() +{ + UID_WRAPPER_INITIAL_RUID=0 UID_WRAPPER_INITIAL_EUID=0 "$CTDB" reloadips 0 + UID_WRAPPER_INITIAL_RUID=0 UID_WRAPPER_INITIAL_EUID=0 "$CTDB" ipreallocate +} + +testit_grep_count "step1: smbstatus 0 sessions" '^0$' 1 smbstatus_num_sessions || failed=$(expr $failed + 1) + +test_smbclient "step2: smbclient against node0[${CTDB_IFACE_IP}]" "${CTDB_IFACE_IP}" "${SHARE}" "ls" -U"${DC_USERNAME}"%"${DC_PASSWORD}" \ + --option="libsmb:client_guid=6112f7d3-9528-4a2a-8861-0ca129aae6c4" \ + || failed=$(expr $failed + 1) + +testit_grep_count "step2: smbstatus 0 sessions" '^0$' 1 smbstatus_num_sessions || failed=$(expr $failed + 1) + +CLI_FORCE_INTERACTIVE=1 +export CLI_FORCE_INTERACTIVE + +testit "step3: start backgroup smbclient against node0[${CTDB_IFACE_IP}]" true || failed=$(expr $failed + 1) + +# Connect a first time +${SMBCLIENT} //"${CTDB_IFACE_IP}"/"${SHARE}" -U"${DC_USERNAME}"%"${DC_PASSWORD}" \ + --option="libsmb:client_guid=6112f7d3-9528-4a2a-8861-0ca129aae6c4" \ + smbclient1-stdout 2>smbclient1-stderr & +CLIENT1_PID=$! + +exec 100>smbclient1-stdin 101smbclient2-stdout 2>smbclient2-stderr & +CLIENT2_PID=$! + +exec 200>smbclient2-stdin 201