Compare commits

...

13 Commits

Author SHA1 Message Date
Ondřej Surý
8fdbf3171a Revert "Skip the runtime ellipsis test"
This reverts commit 161e02845f.
2019-11-26 12:13:07 +01:00
Evan Hunt
8fa02de98d fixed a test failure, some other shell cleanup 2019-11-26 12:11:59 +01:00
Ondřej Surý
cff65624e0 Detect cores on FreeBSD 2019-11-26 12:11:59 +01:00
Ondřej Surý
ca4b4bf421 Request exclusive access when crashing via fatal()
When loading the configuration fails, there might be already other tasks
running and calling OpenSSL library functions.  The OpenSSL on_exit
handler is called when exiting the main process and there's a timing
race between the on_exit function that destroys OpenSSL allocated
resources (threads, locks, ...) and other tasks accessing the very same
resources leading to a crash in the system threading library. Therefore,
the fatal() function needs to request exlusive access to the task
manager to finish the already running tasks and exit only when no other
tasks are running.
2019-11-26 12:11:59 +01:00
Ondřej Surý
bc66044246 Instead of sleeping for a fixed time, wait for named to log specific message in a loop 2019-11-26 12:11:59 +01:00
Ondřej Surý
d52fa06bc1 Use pre-prepared long command line for better portability 2019-11-26 12:11:59 +01:00
Ondřej Surý
34a4ceeb1c Make runtime/tests.sh shellcheck and set -e clean
This mostly comprises of:

* using $(...) instead of `...`
* changing the directories in subshell and not ignoring `cd` return code
* handling every error gracefully instead of ignoring the return code
2019-11-26 12:11:06 +01:00
Ondřej Surý
207b449fab Further improve the runtime tests to look for a specific instead of generic error 2019-11-26 12:11:06 +01:00
Ondřej Surý
d953cabb26 The PATH_MAX on macOS is 1024, we can't override conffile path to test for ellipsis 2019-11-26 12:11:06 +01:00
Ondřej Surý
6d319355b8 Fix couple of no-op tests to actually test something (configuration files were missing) 2019-11-26 12:11:06 +01:00
Ondřej Surý
161e02845f Skip the runtime ellipsis test 2019-11-26 12:11:06 +01:00
Ondřej Surý
c89ceb5ad3 runtime test: make the pidfiles match the names of configuration files 2019-11-26 12:11:06 +01:00
Ondřej Surý
01688a6cf5 runtime test: use helper function that kills named and waits for the finish 2019-11-26 12:11:06 +01:00
13 changed files with 165 additions and 111 deletions

View File

@@ -201,8 +201,8 @@
#define CHECKFATAL(op, msg) \
do { result = (op); \
if (result != ISC_R_SUCCESS) \
fatal(msg, result); \
if (result != ISC_R_SUCCESS) \
fatal(server, msg, result); \
} while (0) \
/*%
@@ -431,7 +431,8 @@ const char *empty_zones[] = {
};
ISC_PLATFORM_NORETURN_PRE static void
fatal(const char *msg, isc_result_t result) ISC_PLATFORM_NORETURN_POST;
fatal(named_server_t *server,const char *msg, isc_result_t result)
ISC_PLATFORM_NORETURN_POST;
static void
named_server_reload(isc_task_t *task, isc_event_t *event);
@@ -9805,7 +9806,7 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
named_server_t *server = isc_mem_get(mctx, sizeof(*server));
if (server == NULL)
fatal("allocating server object", ISC_R_NOMEMORY);
fatal(server, "allocating server object", ISC_R_NOMEMORY);
server->mctx = mctx;
server->task = NULL;
@@ -10016,7 +10017,15 @@ named_server_destroy(named_server_t **serverp) {
}
static void
fatal(const char *msg, isc_result_t result) {
fatal(named_server_t *server, const char *msg, isc_result_t result) {
if (server != NULL) {
/*
* Prevent races between the OpenSSL on_exit registered
* function and any other OpenSSL calls from other tasks
* by requesting exclusive access to the task manager.
*/
(void)isc_task_beginexclusive(server->task);
}
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_CRITICAL,
"%s: %s", msg, isc_result_totext(result));

View File

@@ -189,13 +189,13 @@ if [ $status != 0 ]; then
echofail "R:$systest:FAIL"
# Do not clean up - we need the evidence.
else
core_dumps="$(find $systest/ -name 'core*' | sort | tr '\n' ' ')"
core_dumps="$(find $systest/ -name 'core*' -or -name '*.core' | sort | tr '\n' ' ')"
assertion_failures=$(find $systest/ -name named.run | xargs grep "assertion failure" | wc -l)
if [ -n "$core_dumps" ]; then
echoinfo "I:$systest:Test claims success despite crashes: $core_dumps"
echofail "R:$systest:FAIL"
# Do not clean up - we need the evidence.
find "$systest/" -name 'core*' | while read -r coredump; do
find "$systest/" -name 'core*' -or -name '*.core' | while read -r coredump; do
SYSTESTDIR="$systest"
echoinfo "D:$systest:backtrace from $coredump start"
binary=$(gdb --batch --core="$coredump" | sed -ne "s/Core was generated by \`//;s/ .*'.$//p;")

File diff suppressed because one or more lines are too long

View File

@@ -14,7 +14,7 @@
options {
query-source address 10.53.0.2;
port @PORT@;
pid-file "named2.pid";
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { fd92:7065:b8e:ffff::2; };
recursion no;

View File

@@ -14,7 +14,7 @@
options {
query-source address 10.53.0.2;
port @PORT@;
pid-file "named3.pid";
pid-file "named.pid";
listen-on { 10.53.0.2; 10.53.0.3; };
listen-on-v6 { fd92:7065:b8e:ffff::2; };
recursion no;

View File

@@ -14,7 +14,7 @@
options {
query-source address 10.53.0.2;
port @PORT@;
pid-file "named4.pid";
pid-file "named-alt3.pid";
lock-file none;
listen-on { 10.53.0.2; 10.53.0.3; };
listen-on-v6 { fd92:7065:b8e:ffff::2; };

View File

@@ -12,7 +12,7 @@
options {
directory "./nope";
port @PORT@;
pid-file "../named.pid";
pid-file "named.pid";
listen-on { 127.0.0.1; };
listen-on-v6 { none; };
recursion no;

View File

@@ -12,7 +12,7 @@
options {
managed-keys-directory "./nope";
port @PORT@;
pid-file "../named.pid";
pid-file "named.pid";
listen-on { 127.0.0.1; };
listen-on-v6 { none; };
recursion no;

View File

@@ -12,7 +12,7 @@
options {
new-zones-directory "./nope";
port @PORT@;
pid-file "../named.pid";
pid-file "named.pid";
listen-on { 127.0.0.1; };
listen-on-v6 { none; };
recursion no;

View File

@@ -11,7 +11,7 @@
options {
port @PORT@;
pid-file "named7.pid";
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { fd92:7065:b8e:ffff::2; };
};

View File

@@ -19,6 +19,9 @@ copy_setports ns2/named1.conf.in ns2/named.conf
copy_setports ns2/named-alt1.conf.in ns2/named-alt1.conf
copy_setports ns2/named-alt2.conf.in ns2/named-alt2.conf
copy_setports ns2/named-alt3.conf.in ns2/named-alt3.conf
copy_setports ns2/named-alt4.conf.in ns2/named-alt4.conf
copy_setports ns2/named-alt5.conf.in ns2/named-alt5.conf
copy_setports ns2/named-alt6.conf.in ns2/named-alt6.conf
mkdir ns2/nope

View File

@@ -9,161 +9,201 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# shellcheck source=conf.sh
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
. "$SYSTEMTESTTOP/conf.sh"
set -e
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
kill_named() {
pidfile="${1}"
if [ ! -r "${pidfile}" ]; then
return 1
fi
pid=$(cat "${pidfile}" 2>/dev/null)
if [ "${pid:+set}" = "set" ]; then
$KILL -15 "${pid}" >/dev/null 2>&1
retries=10
while [ "$retries" -gt 0 ]; do
if ! $KILL -0 "${pid}" >/dev/null 2>&1; then
break
fi
sleep 1
retries=$((retries-1))
done
# Timed-out
if [ "$retries" -eq 0 ]; then
echo_i "failed to kill named ($pidfile)"
return 1
fi
fi
rm -f "${pidfile}"
return 0
}
wait_for_named() {
retries=10
while [ "$retries" -gt 0 ]; do
if grep "$@" >/dev/null 2>&1; then
break
fi
sleep 1
retries=$((retries-1))
done
if [ "$retries" -eq 0 ]; then
return 1
fi
return 0
}
status=0
n=0
n=`expr $n + 1`
n=$((n+1))
echo_i "verifying that named started normally ($n)"
ret=0
[ -s ns2/named.pid ] || ret=1
grep "unable to listen on any configured interface" ns2/named.run > /dev/null && ret=1
grep "another named process" ns2/named.run > /dev/null && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=`expr $n + 1`
n=$((n+1))
echo_i "verifying that named checks for conflicting named processes ($n)"
ret=0
(cd ns2; $NAMED -c named-alt2.conf -D runtime-ns2-extra-2 -X named.lock -m record,size,mctx -d 99 -g -U 4 >> named3.run 2>&1 & )
sleep 2
grep "another named process" ns2/named3.run > /dev/null || ret=1
pid=`cat ns2/named3.pid 2>/dev/null`
test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
(cd ns2 && $NAMED -c named-alt2.conf -D runtime-ns2-extra-2 -X named.lock -m record,size,mctx -d 99 -g -U 4 >> named$n.run 2>&1 & )
wait_for_named "another named process" ns2/named$n.run || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=`expr $n + 1`
n=$((n+1))
echo_i "verifying that 'lock-file none' disables process check ($n)"
ret=0
(cd ns2; $NAMED -c named-alt3.conf -D runtime-ns2-extra-3 -m record,size,mctx -d 99 -g -U 4 >> named4.run 2>&1 & )
sleep 2
grep "another named process" ns2/named4.run > /dev/null && ret=1
pid=`cat ns2/named4.pid 2>/dev/null`
test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
(cd ns2 && $NAMED -c named-alt3.conf -D runtime-ns2-extra-3 -m record,size,mctx -d 99 -g -U 4 >> named$n.run 2>&1 & )
wait_for_named "running$" ns2/named$n.run || ret=1
grep "another named process" ns2/named$n.run > /dev/null && ret=1
kill_named ns2/named-alt3.pid || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=`expr $n + 1`
n=$((n+1))
echo_i "checking that named refuses to reconfigure if working directory is not writable ($n)"
ret=0
copy_setports ns2/named-alt4.conf.in ns2/named.conf
$RNDCCMD 10.53.0.2 reconfig > rndc.out.$n 2>&1
$RNDCCMD 10.53.0.2 reconfig > rndc.out.$n 2>&1 && ret=1
grep "failed: permission denied" rndc.out.$n > /dev/null 2>&1 || ret=1
sleep 1
grep "[^-]directory './nope' is not writable" ns2/named.run > /dev/null 2>&1 || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=`expr $n + 1`
n=$((n+1))
echo_i "checking that named refuses to reconfigure if managed-keys-directory is not writable ($n)"
ret=0
copy_setports ns2/named-alt5.conf.in ns2/named.conf
$RNDCCMD 10.53.0.2 reconfig > rndc.out.$n 2>&1
$RNDCCMD 10.53.0.2 reconfig > rndc.out.$n 2>&1 && ret=1
grep "failed: permission denied" rndc.out.$n > /dev/null 2>&1 || ret=1
sleep 1
grep "managed-keys-directory './nope' is not writable" ns2/named.run > /dev/null 2>&1 || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=`expr $n + 1`
n=$((n+1))
echo_i "checking that named refuses to reconfigure if new-zones-directory is not writable ($n)"
ret=0
copy_setports ns2/named-alt6.conf.in ns2/named.conf
$RNDCCMD 10.53.0.2 reconfig > rndc.out.$n 2>&1
$RNDCCMD 10.53.0.2 reconfig > rndc.out.$n 2>&1 && ret=1
grep "failed: permission denied" rndc.out.$n > /dev/null 2>&1 || ret=1
sleep 1
grep "new-zones-directory './nope' is not writable" ns2/named.run > /dev/null 2>&1 || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=`expr $n + 1`
n=$((n+1))
echo_i "checking that named recovers when configuration file is valid again ($n)"
ret=0
copy_setports ns2/named1.conf.in ns2/named.conf
$RNDCCMD 10.53.0.2 reconfig > rndc.out.$n 2>&1 || ret=1
[ -s ns2/named.pid ] || ret=1
kill_named ns2/named.pid || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=$((n+1))
echo_i "checking that named refuses to start if working directory is not writable ($n)"
ret=0
cd ns2
$NAMED -c named-alt4.conf -D runtime-ns2-extra-4 -d 99 -g > named4.run 2>&1 &
sleep 2
grep "exiting (due to fatal error)" named4.run > /dev/null || ret=1
# pidfile could be in either place depending on whether the directory
# successfully changed.
pid=`cat named.pid 2>/dev/null`
test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1
pid=`cat ../named.pid 2>/dev/null`
test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1
cd ..
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
(cd ns2 && $NAMED -c named-alt4.conf -D runtime-ns2-extra-4 -d 99 -g > named$n.run 2>&1 &)
wait_for_named "exiting (due to fatal error)" ns2/named$n.run || ret=1
grep "[^-]directory './nope' is not writable" ns2/named$n.run > /dev/null 2>&1 || ret=1
kill_named ns2/named.pid && ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=`expr $n + 1`
n=$((n+1))
echo_i "checking that named refuses to start if managed-keys-directory is not writable ($n)"
ret=0
cd ns2
$NAMED -c named-alt5.conf -D runtime-ns2-extra-5 -d 99 -g > named5.run 2>&1 &
sleep 2
grep "exiting (due to fatal error)" named5.run > /dev/null || ret=1
# pidfile could be in either place depending on whether the directory
# successfully changed.
pid=`cat named.pid 2>/dev/null`
test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1
pid=`cat ../named.pid 2>/dev/null`
test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1
cd ..
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
(cd ns2 && $NAMED -c named-alt5.conf -D runtime-ns2-extra-5 -d 99 -g > named$n.run 2>&1 &)
wait_for_named "exiting (due to fatal error)" ns2/named$n.run || ret=1
grep "managed-keys-directory './nope' is not writable" ns2/named$n.run > /dev/null 2>&1 || ret=1
kill_named named.pid && ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=`expr $n + 1`
n=$((n+1))
echo_i "checking that named refuses to start if new-zones-directory is not writable ($n)"
ret=0
(cd ns2 && $NAMED -c named-alt6.conf -D runtime-ns2-extra-6 -d 99 -g > named$n.run 2>&1 &)
wait_for_named "exiting (due to fatal error)" ns2/named$n.run || ret=1
grep "new-zones-directory './nope' is not writable" ns2/named$n.run > /dev/null 2>&1 || ret=1
kill_named ns2/named.pid && ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=$((n+1))
echo_i "checking that named logs control characters in octal notation ($n)"
ret=0
SPEC_DIR=`cat ctrl-char-dir-name`
SPEC_DIR=$(cat ctrl-char-dir-name)
mkdir "ns2/${SPEC_DIR}"
copy_setports ns2/named-alt7.conf.in "ns2/${SPEC_DIR}/named.conf"
cd ns2
$NAMED -c "${SPEC_DIR}/named.conf" -d 99 -g > named6.run 2>&1 &
sleep 2
grep 'running as.*\\177\\033' named6.run > /dev/null || ret=1
pid=`cat named7.pid 2>/dev/null`
test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1
cd ..
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
(cd ns2 && $NAMED -c "${SPEC_DIR}/named.conf" -d 99 -g > named$n.run 2>&1 &)
wait_for_named "running$" ns2/named$n.run || ret=1
grep 'running as.*\\177\\033' ns2/named$n.run > /dev/null || ret=1
kill_named ns2/named.pid || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=`expr $n + 1`
n=$((n+1))
echo_i "checking that named escapes special characters in the logs ($n)"
ret=0
SPEC_DIR="$;"
mkdir "ns2/${SPEC_DIR}"
copy_setports ns2/named-alt7.conf.in "ns2/${SPEC_DIR}/named.conf"
cd ns2
$NAMED -c "${SPEC_DIR}/named.conf" -d 99 -g > named7.run 2>&1 &
sleep 2
grep 'running as.*\\$\\;' named7.run > /dev/null || ret=1
pid=`cat named7.pid 2>/dev/null`
test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1
cd ..
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
(cd ns2 && $NAMED -c "${SPEC_DIR}/named.conf" -d 99 -g > named$n.run 2>&1 &)
wait_for_named "running$" ns2/named$n.run || ret=1
grep 'running as.*\\$\\;' ns2/named$n.run > /dev/null || ret=1
kill_named ns2/named.pid || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=`expr $n + 1`
n=$((n+1))
echo_i "checking that named logs an ellipsis when the command line is larger than 8k bytes ($n)"
ret=0
SPEC_DIR=`yes | head -10000 | tr -d '\n'`
cd ns2
$NAMED -c "${SPEC_DIR}/named.conf" -d 99 -g > named8.run 2>&1 &
sleep 2
grep "running as.*\.\.\.$" named8.run > /dev/null || ret=1
pid=`cat named7.pid 2>/dev/null`
test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1
cd ..
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
LONG_CMD_LINE=$(cat long-cmd-line)
copy_setports ns2/named-alt7.conf.in "ns2/named-alt7.conf"
# shellcheck disable=SC2086
(cd ns2 && $NAMED $LONG_CMD_LINE -c "named-alt7.conf" -g > named$n.run 2>&1 &)
wait_for_named "running$" ns2/named$n.run || ret=1
grep "running as.*\.\.\.$" ns2/named$n.run > /dev/null || ret=1
kill_named ns2/named.pid || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=`expr $n + 1`
n=$((n+1))
echo_i "verifying that named switches UID ($n)"
if [ "`id -u`" = 0 ] && [ ! "$CYGWIN" ]; then
if [ "`id -u`" -eq 0 ] && [ ! "$CYGWIN" ]; then
ret=0
TEMP_NAMED_DIR=`mktemp -d`
if [ -d "${TEMP_NAMED_DIR}" ]; then
@@ -175,14 +215,14 @@ if [ "`id -u`" = 0 ] && [ ! "$CYGWIN" ]; then
[ -s "${TEMP_NAMED_DIR}/named9.pid" ] || ret=1
grep "loading configuration: permission denied" "${TEMP_NAMED_DIR}/named9.run" > /dev/null && ret=1
pid=`cat "${TEMP_NAMED_DIR}/named9.pid" 2>/dev/null`
test "${pid:+set}" = set && $KILL -15 "${pid}" >/dev/null 2>&1
[ "${pid:+set}" = "set" ] && $KILL -15 "${pid}" >/dev/null 2>&1
mv "${TEMP_NAMED_DIR}" ns2/
else
echo_i "mktemp failed"
ret=1
fi
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
else
echo_i "skipped, not running as root or running on Windows"
fi

View File

@@ -1009,6 +1009,7 @@
./bin/tests/system/runtime/README TXT.BRIEF 2014,2016,2018,2019
./bin/tests/system/runtime/clean.sh SH 2014,2015,2016,2017,2018,2019
./bin/tests/system/runtime/ctrl-char-dir-name X 2019
./bin/tests/system/runtime/long-cmd-line X 2019
./bin/tests/system/runtime/setup.sh SH 2015,2016,2017,2018,2019
./bin/tests/system/runtime/tests.sh SH 2014,2015,2016,2017,2018,2019
./bin/tests/system/send.pl PERL 2001,2004,2007,2011,2012,2016,2018,2019