From 95a10b4ce541ae945457ad06a9d4381fe075bded Mon Sep 17 00:00:00 2001 From: Mats Erik Andersson Date: Wed, 11 May 2011 12:56:03 +0200 Subject: [PATCH] syslogd: Dereferencing NULL error. Permanent host lookup failures must lead to a discarded forwarding request. A new test script includes the verification of this ability. --- ChangeLog | 9 +++ src/syslogd.c | 15 ++++-- tests/Makefile.am | 6 ++ tests/syslogd.sh | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 tests/syslogd.sh diff --git a/ChangeLog b/ChangeLog index 09cdd2c..458b064 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-05-11 Mats Erik Andersson + + * src/syslogd.d (fprintlog): Sanity check on `f->f_prevhost' + to avoid deferencing NULL. + (cfline): A permanently failed DNS lookup must produce F_UNUSED. + * tests/syslogd.sh: New file. + * tests/Makefile.am (dist_check_SCRIPTS) [ENABLE_logger && + ENABLE_syslogd]: Add `syslogd.sh'. + 2011-05-09 Simon Josefsson * bootstrap.conf (gnulib_modules): Removed 'exit' from list. diff --git a/src/syslogd.c b/src/syslogd.c index 5927f9f..0e94d84 100644 --- a/src/syslogd.c +++ b/src/syslogd.c @@ -1148,9 +1148,12 @@ fprintlog (struct filed *f, const char *from, int flags, const char *msg) v->iov_len = 1; v++; } - v->iov_base = f->f_prevhost; - v->iov_len = strlen (v->iov_base); - v++; + if (f->f_prevhost) + { + v->iov_base = f->f_prevhost; + v->iov_len = strlen (v->iov_base); + v++; + } v->iov_base = (char *) " "; v->iov_len = 1; v++; @@ -1919,7 +1922,11 @@ cfline (const char *line, struct filed *f) hp = gethostbyname (p); if (hp == NULL) { - f->f_type = F_FORW_UNKN; + extern int h_errno; + if (h_errno == NO_DATA || h_errno == HOST_NOT_FOUND) + f->f_type = F_UNUSED; /* No recovery possible. */ + else + f->f_type = F_FORW_UNKN; /* Temporary failure. */ f->f_prevcount = INET_RETRY_MAX; f->f_time = time ((time_t *) 0); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 846f24c..a70193d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -40,6 +40,12 @@ dist_check_SCRIPTS += tftp.sh endif endif endif +if ENABLE_logger +if ENABLE_syslogd +dist_check_SCRIPTS += syslogd.sh +endif +endif + TESTS = $(check_PROGRAMS) $(dist_check_SCRIPTS) TESTS_ENVIRONMENT = EXEEXT=$(EXEEXT) diff --git a/tests/syslogd.sh b/tests/syslogd.sh new file mode 100644 index 0000000..8b0cd88 --- /dev/null +++ b/tests/syslogd.sh @@ -0,0 +1,140 @@ +#!/bin/sh + +# Copyright (C) 2011 Free Software Foundation, Inc. +# +# This file is part of GNU Inetutils. +# +# GNU Inetutils is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or (at +# your option) any later version. +# +# GNU Inetutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see `http://www.gnu.org/licenses/'. + +# Tests to establish functionality of SYSLOG daemon. +# + +# Keep any external assignment. +# +: ${IU_TESTDIR:=/tmp/iu_syslog} + +mkdir -p $IU_TESTDIR + +CONF=$IU_TESTDIR/syslog.conf +PID=$IU_TESTDIR/syslogd.pid +OUT=$IU_TESTDIR/messages +: ${SOCKET:=$IU_TESTDIR/log} + +IU_SYSLOGD=./src/syslogd$EXEEXT +IU_LOGGER=./src/logger$EXEEXT + +# All messages intended for post-detection are +# to be uniformly tagged. +TAG="syslogd-test" + +# Step out of `tests/', should the invokation +# have been made there. +# +[ -d ../src ] && cd .. + +if [ ! -x $IU_SYSLOGD ]; then + echo "Missing executable 'syslogd'. Failing." + exit 1; +fi + +if [ ! -x $IU_LOGGER ]; then + echo "Missing executable 'logger'. Failing." + exit 1 +fi + +# Remove old messages. +rm -f $OUT $PID + +# Full testing needs a superuser. Report this. +if [ "$USER" != "root" ]; then + cat <<-EOT + WARNING!! + Disabling INET server tests since you seem + to be underprivileged. + EOT +fi + +# A minimal, catch-all configuration. +# +cat > $CONF <<-EOT + *.* $OUT + *.* @not.in.existence +EOT + +# Attempt to start the server after first +# building the desired option list. +# +## Base configuration. +IU_OPTIONS="--rcfile=$CONF --pidfile=$PID --socket=$SOCKET" +## Enable INET service when running as root. +if [ "$USER" = "root" ]; then + IU_OPTIONS="$IU_OPTIONS --inet" +fi +## Bring in additional options from command line. +## Disable kernel messages otherwise. +: OPTIONS=${OPTIONS:=--no-klog} +IU_OPTIONS="$IU_OPTIONS $OPTIONS" + +$IU_SYSLOGD $IU_OPTIONS + +# Wait a moment in order to avoid an obvious +# race condition with the server daemon on +# slow systems. +# +sleep 1 + +# Test to see whether the service got started. +# +if [ ! -r $PID ]; then + echo "The service daemon never started. Failing." + exit 1 +fi + +# Declare the number of implemented tests, +# as well as an exit code. +# +TESTCASES=0 +EXITCODE=1 + +# Send messages on two sockets: IPv4 and UNIX. +# +TESTCASES=$((TESTCASES + 1)) +$IU_LOGGER -h $SOCKET -p user -t $TAG "Sending BSD message." + +if [ "$USER" = "root" ]; then + TESTCASES=$((TESTCASES + 1)) + $IU_LOGGER -4 -h localhost -p user -t $TAG "Sending IPv4 message." +fi + +# Detection of registered messages. +# +TEXTLINES="$(grep $TAG $OUT | wc -l)" + +if [ -n "${VERBOSE+yes}" ]; then + grep $TAG $OUT +fi + +echo "Registered $TEXTLINES lines out of $TESTCASES." + +if [ "$TEXTLINES" -eq "$TESTCASES" ]; then + echo "Successful testing." + EXITCODE=0 +else + echo "Failing some tests." +fi + +# Remove the daemon process. +[ -r $PID ] && kill "$(cat $PID)" + +exit $EXITCODE -- 1.7.4.4