From d41692264a2b1a54082ef936d2830cd9d4fa6b62 Mon Sep 17 00:00:00 2001 From: Jackie Huang Date: Wed, 6 May 2020 15:45:06 +0800 Subject: [PATCH] dnsmasq: add version 2.76 and align with stx 3.0 - Add recipe for version 2.76 and set as the preferred version (or it will select 2.80) - Add patches from dnsmasq-2.76-7.el7.tis.7.src.rpm - Align the spec file from dnsmasq-2.76-7.el7.tis.7.src.rpm - Add dependency on dnsmasq so it will be installed in image Issue-ID: INF-85 Signed-off-by: Jackie Huang Change-Id: I0f0ab584686c2aa94b8ec2156f98f1298ea19293 --- .../conf/distro/include/stx-preferred-vers.inc | 1 + .../stx-config-files/config-files_1.0.0.bb | 2 +- .../recipes-support/dnsmasq/dnsmasq/99_dnsmasq | 1 + .../dnsmasq/dnsmasq/dnsmasq-resolvconf-helper | 62 +++ .../dnsmasq/dnsmasq/dnsmasq-resolvconf.service | 17 + .../dnsmasq/dnsmasq/dnsmasq.resolvconf | 84 +++ meta-stx/recipes-support/dnsmasq/dnsmasq/init | 117 +++++ meta-stx/recipes-support/dnsmasq/dnsmasq/lua.patch | 26 + .../stx/close-tftp-sockets-immediately.patch | 28 + .../stx/dnsmasq-2.76-CVE-2017-14491-2.patch | 68 +++ .../dnsmasq/stx/dnsmasq-2.76-CVE-2017-14491.patch | 262 ++++++++++ .../dnsmasq/stx/dnsmasq-2.76-CVE-2017-14492.patch | 31 ++ .../dnsmasq/stx/dnsmasq-2.76-CVE-2017-14493.patch | 30 ++ .../dnsmasq/stx/dnsmasq-2.76-CVE-2017-14494.patch | 30 ++ .../dnsmasq/stx/dnsmasq-2.76-CVE-2017-14495.patch | 41 ++ .../dnsmasq/stx/dnsmasq-2.76-CVE-2017-14496.patch | 66 +++ .../dnsmasq/stx/dnsmasq-2.76-coverity.patch | 254 +++++++++ .../dnsmasq/stx/dnsmasq-2.76-dhcp-script-log.patch | 582 +++++++++++++++++++++ .../stx/dnsmasq-2.76-dns-sleep-resume.patch | 119 +++++ .../dnsmasq/stx/dnsmasq-2.76-file_offset32.patch | 12 + .../stx/dnsmasq-2.76-fix-crash-dns-resume.patch | 29 + ...dnsmasq-2.76-fix-dhcp-option-arrangements.patch | 49 ++ .../dnsmasq/stx/dnsmasq-2.76-gita3303e196.patch | 45 ++ .../dnsmasq/dnsmasq/stx/dnsmasq-2.76-inotify.patch | 14 + .../dnsmasq/stx/dnsmasq-2.76-label-man.patch | 36 ++ .../dnsmasq/stx/dnsmasq-2.76-label-warning.patch | 93 ++++ .../dnsmasq/stx/dnsmasq-2.76-misc-cleanups.patch | 63 +++ .../dnsmasq/stx/dnsmasq-2.76-pftables.patch | 149 ++++++ .../dnsmasq/stx/dnsmasq-2.76-underflow.patch | 74 +++ .../dnsmasq/stx/dnsmasq-2.76-warning-fixes.patch | 60 +++ .../dnsmasq-update-ipv6-leases-from-config.patch | 83 +++ .../dnsmasq/dnsmasq/stx/dnsmasq.service | 9 + meta-stx/recipes-support/dnsmasq/dnsmasq_2.76.bb | 135 +++++ 33 files changed, 2671 insertions(+), 1 deletion(-) create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/99_dnsmasq create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq-resolvconf-helper create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq-resolvconf.service create mode 100755 meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq.resolvconf create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/init create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/lua.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/close-tftp-sockets-immediately.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14491-2.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14491.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14492.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14493.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14494.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14495.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14496.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-coverity.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-dhcp-script-log.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-dns-sleep-resume.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-file_offset32.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-fix-crash-dns-resume.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-fix-dhcp-option-arrangements.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-gita3303e196.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-inotify.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-label-man.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-label-warning.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-misc-cleanups.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-pftables.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-underflow.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-warning-fixes.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-update-ipv6-leases-from-config.patch create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq.service create mode 100644 meta-stx/recipes-support/dnsmasq/dnsmasq_2.76.bb diff --git a/meta-stx/conf/distro/include/stx-preferred-vers.inc b/meta-stx/conf/distro/include/stx-preferred-vers.inc index 81f949b..d48c279 100644 --- a/meta-stx/conf/distro/include/stx-preferred-vers.inc +++ b/meta-stx/conf/distro/include/stx-preferred-vers.inc @@ -14,6 +14,7 @@ # limitations under the License. PREFERRED_VERSION_ceph = "13.2.2" +PREFERRED_VERSION_dnsmasq = "2.76" PREFERRED_VERSION_keyutils = "1.6" PREFERRED_VERSION_python-voluptuous = "0.8.9" PREFERRED_VERSION_python3-cherrypy = "18.2.0" diff --git a/meta-stx/recipes-core/stx-config-files/config-files_1.0.0.bb b/meta-stx/recipes-core/stx-config-files/config-files_1.0.0.bb index b61260c..cde5170 100644 --- a/meta-stx/recipes-core/stx-config-files/config-files_1.0.0.bb +++ b/meta-stx/recipes-core/stx-config-files/config-files_1.0.0.bb @@ -146,7 +146,7 @@ RDEPENDS_audit-config += " \ audit-python \ " RDEPENDS_dhclient-config += "dhcp-client" -RDEPENDS_dnsmasq-config += "" +RDEPENDS_dnsmasq-config += "dnsmasq" RDEPENDS_docker-config += "docker-ce logrotate " RDEPENDS_initscripts-config += "initscripts" RDEPENDS_filesystem-scripts += "" diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/99_dnsmasq b/meta-stx/recipes-support/dnsmasq/dnsmasq/99_dnsmasq new file mode 100644 index 0000000..f52ce4e --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/99_dnsmasq @@ -0,0 +1 @@ +d root root 0755 /run/dnsmasq none diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq-resolvconf-helper b/meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq-resolvconf-helper new file mode 100644 index 0000000..db54d46 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq-resolvconf-helper @@ -0,0 +1,62 @@ +#!/bin/bash +# +# Borrowing heavily from the dnsmasq initscript's version of support for +# resolvconf, intended for use in systemd-only configurations. +# +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/usr/sbin/dnsmasq +NAME=dnsmasq + +# Most configuration options in /etc/default/dnsmasq are deprecated +# but still honoured. +if [ -r /etc/default/$NAME ]; then + . /etc/default/$NAME +fi + +start_resolvconf() +{ + # If interface "lo" is explicitly disabled in /etc/default/dnsmasq + # Then dnsmasq won't be providing local DNS, so don't add it to + # the resolvconf server set. + for interface in $DNSMASQ_EXCEPT + do + [ $interface = lo ] && return + done + + if [ -x /sbin/resolvconf ] ; then + echo "nameserver 127.0.0.1" | + /sbin/resolvconf -a lo.$NAME + fi + return 0 +} + +stop_resolvconf() +{ + if [ -x /sbin/resolvconf ] ; then + /sbin/resolvconf -d lo.$NAME + fi + return 0 +} + +case "$1" in + start) + start_resolvconf + exit 0 + ;; + stop) + stop_resolvconf + exit 0 + ;; + restart) + stop_resolvconf + start_resolvconf + exit 0 + ;; + *) + echo "Usage: /etc/init.d/$NAME {start|stop|restart}" >&2 + exit 3 + ;; +esac + +exit 0 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq-resolvconf.service b/meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq-resolvconf.service new file mode 100644 index 0000000..2980f7d --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq-resolvconf.service @@ -0,0 +1,17 @@ +[Unit] +Description=DNS forwarder and DHCP server +After=network.target + +[Service] +Type=forking +PIDFile=/run/dnsmasq.pid +ExecStartPre=/usr/bin/dnsmasq --test +ExecStart=/usr/bin/dnsmasq -x /run/dnsmasq.pid -7 /etc/dnsmasq.d --local-service +ExecStartPost=/usr/bin/dnsmasq-resolvconf-helper start +ExecStopPre=/usr/bin/dnsmasq-resolvconf-helper stop +ExecStop=/bin/kill $MAINPID +ExecReload=/bin/kill -HUP $MAINPID + +[Install] +WantedBy=multi-user.target + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq.resolvconf b/meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq.resolvconf new file mode 100755 index 0000000..06cd25c --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/dnsmasq.resolvconf @@ -0,0 +1,84 @@ +#!/bin/sh +# +# Script to update the resolver list for dnsmasq +# +# N.B. Resolvconf may run us even if dnsmasq is not (yet) running. +# If dnsmasq is installed then we go ahead and update the resolver list +# in case dnsmasq is started later. +# +# Assumption: On entry, PWD contains the resolv.conf-type files. +# +# This file is part of the dnsmasq package. +# + +set -e + +RUN_DIR="/run/dnsmasq" +RSLVRLIST_FILE="${RUN_DIR}/resolv.conf" +TMP_FILE="${RSLVRLIST_FILE}_new.$$" +MY_NAME_FOR_RESOLVCONF="dnsmasq" + +[ -x /usr/bin/dnsmasq ] || exit 0 +[ -x /lib/resolvconf/list-records ] || exit 1 + +PATH=/bin:/sbin + +report_err() { echo "$0: Error: $*" >&2 ; } + +# Stores arguments (minus duplicates) in RSLT, separated by spaces +# Doesn't work properly if an argument itself contains whitespace +uniquify() +{ + RSLT="" + while [ "$1" ] ; do + for E in $RSLT ; do + [ "$1" = "$E" ] && { shift ; continue 2 ; } + done + RSLT="${RSLT:+$RSLT }$1" + shift + done +} + +if [ ! -d "$RUN_DIR" ] && ! mkdir --parents --mode=0755 "$RUN_DIR" ; then + report_err "Failed trying to create directory $RUN_DIR" + exit 1 +fi + +RSLVCNFFILES="" +for F in $(/lib/resolvconf/list-records --after "lo.$MY_NAME_FOR_RESOLVCONF") ; do + case "$F" in + "lo.$MY_NAME_FOR_RESOLVCONF") + # Omit own record + ;; + lo.*) + # Include no more records after one for a local nameserver + RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F" + break + ;; + *) + RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F" + ;; + esac +done + +NMSRVRS="" +if [ "$RSLVCNFFILES" ] ; then + uniquify $(sed -n -e 's/^[[:space:]]*nameserver[[:space:]]\+//p' $RSLVCNFFILES) + NMSRVRS="$RSLT" +fi + +# Dnsmasq uses the mtime of $RSLVRLIST_FILE, with a resolution of one second, +# to detect changes in the file. This means that if a resolvconf update occurs +# within one second of the previous one then dnsmasq may fail to notice the +# more recent change. To work around this problem we sleep one second here +# if necessary in order to ensure that the new mtime is different. +if [ -f "$RSLVRLIST_FILE" ] && [ "$(stat -c %X "$RSLVRLIST_FILE")" = "$(date +%s)" ] ; then + sleep 1 +fi + +clean_up() { rm -f "$TMP_FILE" ; } +trap clean_up EXIT +: >| "$TMP_FILE" +for N in $NMSRVRS ; do echo "nameserver $N" >> "$TMP_FILE" ; done +mv -f "$TMP_FILE" "$RSLVRLIST_FILE" + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/init b/meta-stx/recipes-support/dnsmasq/dnsmasq/init new file mode 100644 index 0000000..51c95df --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/init @@ -0,0 +1,117 @@ +#!/bin/sh +DAEMON=/usr/bin/dnsmasq +NAME=dnsmasq +DESC="DNS forwarder and DHCP server" +ARGS="-7 /etc/dnsmasq.d" + +test -f $DAEMON || exit 0 + +set -e + +if [ -r /etc/default/$NAME ] +then + . /etc/default/$NAME +fi + +DNSMASQ_CONF="/etc/dnsmasq.conf" +test "/etc/dnsmasq.d/*" != '/etc/dnsmasq.d/*' && DNSMASQ_CONF="${DNSMASQ_CONF} /etc/dnsmasq.d/*" + +test -z "${PIDFILE}" && PIFILE="/run/dnsmasq.pid" + +if [ -z "$IGNORE_RESOLVCONF" ] +then + egrep -h -q '^no-resolv' ${DNSMASQ_CONF} && IGNORE_RESOLVCONF="yes" +fi + +# RESOLV_CONF: +# If the resolvconf package is installed then use the resolv conf file +# that it provides as the default. Otherwise use /etc/resolv.conf as +# the default. +# +# If IGNORE_RESOLVCONF is set in /etc/default/dnsmasq or an explicit +# filename is set there then this inhibits the use of the resolvconf-provided +# information. +# +# Note that if the resolvconf package is installed it is not possible to +# override it just by configuration in /etc/dnsmasq.conf, it is necessary +# to set IGNORE_RESOLVCONF=yes in /etc/default/dnsmasq. + +test -z "$RESOLV_CONF" -a "$IGNORE_RESOLVCONF" != "yes" -a -x /sbin/resolvconf && \ + RESOLV_CONF=/run/dnsmasq/resolv.conf + +start_resolvconf() +{ + if [ "$IGNORE_RESOLVCONF" != "yes" -a -x /sbin/resolvconf ] + then + echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.$NAME + fi + : +} + +stop_resolvconf() +{ + if [ "$IGNORE_RESOLVCONF" != "yes" -a -x /sbin/resolvconf ] + then + /sbin/resolvconf -d lo.$NAME + fi + : +} + +case "$1" in + start) + echo -n "starting $DESC: $NAME... " + test -d /var/lib/misc/ || mkdir /var/lib/misc/ + start-stop-daemon -S -x $DAEMON -- $ARGS \ + ${RESOLV_CONF:+ -r $RESOLV_CONF} \ + ${PIDFILE:+ -x $PIDFILE} + test $? -eq 0 && start_resolvconf + echo "done." + ;; + stop) + echo -n "stopping $DESC: $NAME... " + stop_resolvconf + start-stop-daemon -K -x $DAEMON + echo "done." + ;; + status) + echo -n "dnsmasq " + start-stop-daemon -q -K -t -x $DAEMON + RET=$? + if [ "$RET" = "0" ]; then + PID=`cat ${PIDFILE}` + echo "($PID) is running" + else + echo "is not running" + exit $RET + fi + ;; + restart) + echo "restarting $DESC: $NAME... " + $0 stop + $0 start + echo "done." + ;; + reload) + echo -n "reloading $DESC: $NAME... " + killall -HUP $(basename ${DAEMON}) + echo "done." + ;; + systemd-start-resolvconf) + start_resolvconf + ;; + systemd-stop-resolvconf) + stop_resolvconf + ;; + systemd-exec) + test -d /var/lib/misc/ || mkdir /var/lib/misc/ + exec $DAEMON --keep-in-foreground $ARGS \ + ${RESOLV_CONF:+ -r $RESOLV_CONF} \ + ${PIDFILE:+ -x $PIDFILE} + ;; + *) + echo "Usage: $0 {start|stop|status|restart|reload}" + exit 1 + ;; +esac + +exit 0 diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/lua.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/lua.patch new file mode 100644 index 0000000..6281c78 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/lua.patch @@ -0,0 +1,26 @@ +From 7a7ba871bc9280e76c13ffd87c7d9aaa72dad88d Mon Sep 17 00:00:00 2001 +From: Joe MacDonald +Date: Tue, 9 Sep 2014 10:24:58 -0400 +Subject: [PATCH] Upstream-status: Inappropriate [OE specific] + +Signed-off-by: Christopher Larson + +--- + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index dd0513b..c49e84f 100644 +--- a/Makefile ++++ b/Makefile +@@ -57,8 +57,8 @@ idn_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) - + idn_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --libs libidn` + ct_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --cflags libnetfilter_conntrack` + ct_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --libs libnetfilter_conntrack` +-lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.1` +-lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.1` ++lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua` ++lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua` + nettle_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --cflags nettle hogweed` + nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --libs nettle hogweed` + gmp_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC NO_GMP --copy -lgmp` diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/close-tftp-sockets-immediately.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/close-tftp-sockets-immediately.patch new file mode 100644 index 0000000..9ca838b --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/close-tftp-sockets-immediately.patch @@ -0,0 +1,28 @@ +From 858e259bf7125695c068301d0ef56cc4750d6544 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Thu, 15 Sep 2016 13:32:03 -0400 +Subject: [PATCH 1/1] Close tftp sockets immediately + +--- + src/tftp.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/tftp.c b/src/tftp.c +index d7d050f..ecc6ce8 100644 +--- a/src/tftp.c ++++ b/src/tftp.c +@@ -768,9 +768,11 @@ int do_tftp_script_run(void) + if ((transfer = daemon->tftp_done_trans)) + { + daemon->tftp_done_trans = transfer->next; ++#if 0 /* Disable delayed closing of TFTP UDP socket */ + #ifdef HAVE_SCRIPT + queue_tftp(transfer->file->size, transfer->file->filename, &transfer->peer); + #endif ++#endif + free_transfer(transfer); + return 1; + } +-- +1.9.1 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14491-2.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14491-2.patch new file mode 100644 index 0000000..3935566 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14491-2.patch @@ -0,0 +1,68 @@ +From 62cb936cb7ad5f219715515ae7d32dd281a5aa1f Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Tue, 26 Sep 2017 22:00:11 +0100 +Subject: Security fix, CVE-2017-14491, DNS heap buffer overflow. + +Further fix to 0549c73b7ea6b22a3c49beb4d432f185a81efcbc +Handles case when RR name is not a pointer to the question, +only occurs for some auth-mode replies, therefore not +detected by fuzzing (?) +--- + src/rfc1035.c | 27 +++++++++++++++------------ + 1 file changed, 15 insertions(+), 12 deletions(-) + +diff --git a/src/rfc1035.c b/src/rfc1035.c +index 27af023..56ab88b 100644 +--- a/src/rfc1035.c ++++ b/src/rfc1035.c +@@ -1086,32 +1086,35 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int + + va_start(ap, format); /* make ap point to 1st unamed argument */ + +- /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */ +- CHECK_LIMIT(12); +- + if (nameoffset > 0) + { ++ CHECK_LIMIT(2); + PUTSHORT(nameoffset | 0xc000, p); + } + else + { + char *name = va_arg(ap, char *); +- if (name) +- p = do_rfc1035_name(p, name, limit); +- if (!p) +- { +- va_end(ap); +- goto truncated; +- } +- ++ if (name && !(p = do_rfc1035_name(p, name, limit))) ++ { ++ va_end(ap); ++ goto truncated; ++ } ++ + if (nameoffset < 0) + { ++ CHECK_LIMIT(2); + PUTSHORT(-nameoffset | 0xc000, p); + } + else +- *p++ = 0; ++ { ++ CHECK_LIMIT(1); ++ *p++ = 0; ++ } + } + ++ /* type (2) + class (2) + ttl (4) + rdlen (2) */ ++ CHECK_LIMIT(10); ++ + PUTSHORT(type, p); + PUTSHORT(class, p); + PUTLONG(ttl, p); /* TTL */ +-- +2.7.4 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14491.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14491.patch new file mode 100644 index 0000000..4d8dbd5 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14491.patch @@ -0,0 +1,262 @@ +From 8868a04895b27d42d42e364f1a0c0196c1505b04 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 18:17:11 +0100 +Subject: [PATCH 1/9] Security fix, CVE-2017-14491 DNS heap buffer + overflow. + + Fix heap overflow in DNS code. This is a potentially serious + security hole. It allows an attacker who can make DNS + requests to dnsmasq, and who controls the contents of + a domain, which is thereby queried, to overflow + (by 2 bytes) a heap buffer and either crash, or + even take control of, dnsmasq. +--- + src/dnsmasq.h | 2 +- + src/dnssec.c | 2 +- + src/option.c | 2 +- + src/rfc1035.c | 50 +++++++++++++++++++++++++++++++++++++++++--------- + src/rfc2131.c | 4 ++-- + src/rfc3315.c | 4 ++-- + src/util.c | 7 ++++++- + 7 files changed, 54 insertions(+), 17 deletions(-) + +diff --git a/src/dnsmasq.h b/src/dnsmasq.h +index 1179492..06e5579 100644 +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -1162,7 +1162,7 @@ u32 rand32(void); + u64 rand64(void); + int legal_hostname(char *c); + char *canonicalise(char *s, int *nomem); +-unsigned char *do_rfc1035_name(unsigned char *p, char *sval); ++unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit); + void *safe_malloc(size_t size); + void safe_pipe(int *fd, int read_noblock); + void *whine_malloc(size_t size); +diff --git a/src/dnssec.c b/src/dnssec.c +index 3c77c7d..f45c804 100644 +--- a/src/dnssec.c ++++ b/src/dnssec.c +@@ -2227,7 +2227,7 @@ size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char + + p = (unsigned char *)(header+1); + +- p = do_rfc1035_name(p, name); ++ p = do_rfc1035_name(p, name, NULL); + *p++ = 0; + PUTSHORT(type, p); + PUTSHORT(class, p); +diff --git a/src/option.c b/src/option.c +index eb78b1a..3469f53 100644 +--- a/src/option.c ++++ b/src/option.c +@@ -1378,7 +1378,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags) + } + + p = newp; +- end = do_rfc1035_name(p + len, dom); ++ end = do_rfc1035_name(p + len, dom, NULL); + *end++ = 0; + len = end - p; + free(dom); +diff --git a/src/rfc1035.c b/src/rfc1035.c +index 24d08c1..78410d6 100644 +--- a/src/rfc1035.c ++++ b/src/rfc1035.c +@@ -1049,6 +1049,7 @@ int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bog + return 0; + } + ++ + int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp, + unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...) + { +@@ -1058,12 +1059,21 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int + unsigned short usval; + long lval; + char *sval; ++#define CHECK_LIMIT(size) \ ++ if (limit && p + (size) > (unsigned char*)limit) \ ++ { \ ++ va_end(ap); \ ++ goto truncated; \ ++ } + + if (truncp && *truncp) + return 0; +- ++ + va_start(ap, format); /* make ap point to 1st unamed argument */ +- ++ ++ /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */ ++ CHECK_LIMIT(12); ++ + if (nameoffset > 0) + { + PUTSHORT(nameoffset | 0xc000, p); +@@ -1072,7 +1082,13 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int + { + char *name = va_arg(ap, char *); + if (name) +- p = do_rfc1035_name(p, name); ++ p = do_rfc1035_name(p, name, limit); ++ if (!p) ++ { ++ va_end(ap); ++ goto truncated; ++ } ++ + if (nameoffset < 0) + { + PUTSHORT(-nameoffset | 0xc000, p); +@@ -1093,6 +1109,7 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int + { + #ifdef HAVE_IPV6 + case '6': ++ CHECK_LIMIT(IN6ADDRSZ); + sval = va_arg(ap, char *); + memcpy(p, sval, IN6ADDRSZ); + p += IN6ADDRSZ; +@@ -1100,36 +1117,47 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int + #endif + + case '4': ++ CHECK_LIMIT(INADDRSZ); + sval = va_arg(ap, char *); + memcpy(p, sval, INADDRSZ); + p += INADDRSZ; + break; + + case 'b': ++ CHECK_LIMIT(1); + usval = va_arg(ap, int); + *p++ = usval; + break; + + case 's': ++ CHECK_LIMIT(2); + usval = va_arg(ap, int); + PUTSHORT(usval, p); + break; + + case 'l': ++ CHECK_LIMIT(4); + lval = va_arg(ap, long); + PUTLONG(lval, p); + break; + + case 'd': +- /* get domain-name answer arg and store it in RDATA field */ +- if (offset) +- *offset = p - (unsigned char *)header; +- p = do_rfc1035_name(p, va_arg(ap, char *)); +- *p++ = 0; ++ /* get domain-name answer arg and store it in RDATA field */ ++ if (offset) ++ *offset = p - (unsigned char *)header; ++ p = do_rfc1035_name(p, va_arg(ap, char *), limit); ++ if (!p) ++ { ++ va_end(ap); ++ goto truncated; ++ } ++ CHECK_LIMIT(1); ++ *p++ = 0; + break; + + case 't': + usval = va_arg(ap, int); ++ CHECK_LIMIT(usval); + sval = va_arg(ap, char *); + if (usval != 0) + memcpy(p, sval, usval); +@@ -1141,20 +1169,24 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int + usval = sval ? strlen(sval) : 0; + if (usval > 255) + usval = 255; ++ CHECK_LIMIT(usval + 1); + *p++ = (unsigned char)usval; + memcpy(p, sval, usval); + p += usval; + break; + } + ++#undef CHECK_LIMIT + va_end(ap); /* clean up variable argument pointer */ + + j = p - sav - 2; +- PUTSHORT(j, sav); /* Now, store real RDLength */ ++ /* this has already been checked against limit before */ ++ PUTSHORT(j, sav); /* Now, store real RDLength */ + + /* check for overflow of buffer */ + if (limit && ((unsigned char *)limit - p) < 0) + { ++truncated: + if (truncp) + *truncp = 1; + return 0; +diff --git a/src/rfc2131.c b/src/rfc2131.c +index 8b99d4b..75893a6 100644 +--- a/src/rfc2131.c ++++ b/src/rfc2131.c +@@ -2420,10 +2420,10 @@ static void do_options(struct dhcp_context *context, + + if (fqdn_flags & 0x04) + { +- p = do_rfc1035_name(p, hostname); ++ p = do_rfc1035_name(p, hostname, NULL); + if (domain) + { +- p = do_rfc1035_name(p, domain); ++ p = do_rfc1035_name(p, domain, NULL); + *p++ = 0; + } + } +diff --git a/src/rfc3315.c b/src/rfc3315.c +index 3f4d69c..73bdee4 100644 +--- a/src/rfc3315.c ++++ b/src/rfc3315.c +@@ -1472,10 +1472,10 @@ static struct dhcp_netid *add_options(struct state *state, int do_refresh) + if ((p = expand(len + 2))) + { + *(p++) = state->fqdn_flags; +- p = do_rfc1035_name(p, state->hostname); ++ p = do_rfc1035_name(p, state->hostname, NULL); + if (state->send_domain) + { +- p = do_rfc1035_name(p, state->send_domain); ++ p = do_rfc1035_name(p, state->send_domain, NULL); + *p = 0; + } + } +diff --git a/src/util.c b/src/util.c +index 1a9f228..be9f8a6 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -218,15 +218,20 @@ char *canonicalise(char *in, int *nomem) + return ret; + } + +-unsigned char *do_rfc1035_name(unsigned char *p, char *sval) ++unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit) + { + int j; + + while (sval && *sval) + { ++ if (limit && p + 1 > (unsigned char*)limit) ++ return p; ++ + unsigned char *cp = p++; + for (j = 0; *sval && (*sval != '.'); sval++, j++) + { ++ if (limit && p + 1 > (unsigned char*)limit) ++ return p; + #ifdef HAVE_DNSSEC + if (option_bool(OPT_DNSSEC_VALID) && *sval == NAME_ESCAPE) + *p++ = (*(++sval))-1; +-- +2.9.5 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14492.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14492.patch new file mode 100644 index 0000000..b381148 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14492.patch @@ -0,0 +1,31 @@ +From c14b8b511ac55f6933aebefbd6cc27c1ec74ad58 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 18:47:15 +0100 +Subject: [PATCH 2/9] Security fix, CVE-2017-14492, DHCPv6 RA heap + overflow. + + Fix heap overflow in IPv6 router advertisement code. + This is a potentially serious security hole, as a + crafted RA request can overflow a buffer and crash or + control dnsmasq. Attacker must be on the local network. +--- + src/radv.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/radv.c b/src/radv.c +index 749b666..d09fe0e 100644 +--- a/src/radv.c ++++ b/src/radv.c +@@ -198,6 +198,9 @@ void icmp6_packet(time_t now) + /* look for link-layer address option for logging */ + if (sz >= 16 && packet[8] == ICMP6_OPT_SOURCE_MAC && (packet[9] * 8) + 8 <= sz) + { ++ if ((packet[9] * 8 - 2) * 3 - 1 >= MAXDNAME) { ++ return; ++ } + print_mac(daemon->namebuff, &packet[10], (packet[9] * 8) - 2); + mac = daemon->namebuff; + } +-- +2.9.5 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14493.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14493.patch new file mode 100644 index 0000000..5634803 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14493.patch @@ -0,0 +1,30 @@ +From 5086b12a4b1269d1576b5bab01f72c6fa19c55bc Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 18:52:50 +0100 +Subject: [PATCH 3/9] Security fix, CVE-2017-14493, DHCPv6 - Stack buffer + overflow. + + Fix stack overflow in DHCPv6 code. An attacker who can send + a DHCPv6 request to dnsmasq can overflow the stack frame and + crash or control dnsmasq. +--- + src/rfc3315.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/rfc3315.c b/src/rfc3315.c +index 73bdee4..8d18a28 100644 +--- a/src/rfc3315.c ++++ b/src/rfc3315.c +@@ -206,6 +206,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz, + /* RFC-6939 */ + if ((opt = opt6_find(opts, end, OPTION6_CLIENT_MAC, 3))) + { ++ if (opt6_len(opt) - 2 > DHCP_CHADDR_MAX) { ++ return 0; ++ } + state->mac_type = opt6_uint(opt, 0, 2); + state->mac_len = opt6_len(opt) - 2; + memcpy(&state->mac[0], opt6_ptr(opt, 2), state->mac_len); +-- +2.9.5 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14494.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14494.patch new file mode 100644 index 0000000..3743a32 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14494.patch @@ -0,0 +1,30 @@ +From 8c8fe650dc17aad0fbafc920fde719218dc4568d Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 20:05:11 +0100 +Subject: [PATCH 4/9] Security fix, CVE-2017-14494, Infoleak handling + DHCPv6 forwarded requests. + + Fix information leak in DHCPv6. A crafted DHCPv6 packet can + cause dnsmasq to forward memory from outside the packet + buffer to a DHCPv6 server when acting as a relay. +--- + src/rfc3315.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/rfc3315.c b/src/rfc3315.c +index 8d18a28..03b3f84 100644 +--- a/src/rfc3315.c ++++ b/src/rfc3315.c +@@ -216,6 +216,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz, + + for (opt = opts; opt; opt = opt6_next(opt, end)) + { ++ if (opt6_ptr(opt, 0) + opt6_len(opt) >= end) { ++ return 0; ++ } + int o = new_opt6(opt6_type(opt)); + if (opt6_type(opt) == OPTION6_RELAY_MSG) + { +-- +2.9.5 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14495.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14495.patch new file mode 100644 index 0000000..8ca5d0f --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14495.patch @@ -0,0 +1,41 @@ +From f2ad2cecb55825f7e4409222de1688b9ceebceda Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 20:16:50 +0100 +Subject: [PATCH 6/9] Security fix, CVE-2017-14495, OOM in DNS response + creation. + + Fix out-of-memory Dos vulnerability. An attacker which can + send malicious DNS queries to dnsmasq can trigger memory + allocations in the add_pseudoheader function + The allocated memory is never freed which leads to a DoS + through memory exhaustion. dnsmasq is vulnerable only + if one of the following option is specified: + --add-mac, --add-cpe-id or --add-subnet. +--- + src/edns0.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/edns0.c b/src/edns0.c +index eed135e..5bdc133 100644 +--- a/src/edns0.c ++++ b/src/edns0.c +@@ -192,9 +192,15 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l + !(p = skip_section(p, + ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount), + header, plen))) ++ { ++ free(buff); + return plen; ++ } + if (p + 11 > limit) +- return plen; /* Too big */ ++ { ++ free(buff); ++ return plen; /* Too big */ ++ } + *p++ = 0; /* empty name */ + PUTSHORT(T_OPT, p); + PUTSHORT(udp_sz, p); /* max packet length, 512 if not given in EDNS0 header */ +-- +2.9.5 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14496.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14496.patch new file mode 100644 index 0000000..f32b919 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-CVE-2017-14496.patch @@ -0,0 +1,66 @@ +From 5ab67e936085a9e584c9b3e43f442ef5bee7f40e Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 20:11:58 +0100 +Subject: [PATCH 5/9] Security fix, CVE-2017-14496, Integer underflow in + DNS response creation. + + Fix DoS in DNS. Invalid boundary checks in the + add_pseudoheader function allows a memcpy call with negative + size An attacker which can send malicious DNS queries + to dnsmasq can trigger a DoS remotely. + dnsmasq is vulnerable only if one of the following option is + specified: --add-mac, --add-cpe-id or --add-subnet. +--- + src/edns0.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/edns0.c b/src/edns0.c +index d2b514b..eed135e 100644 +--- a/src/edns0.c ++++ b/src/edns0.c +@@ -144,7 +144,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l + GETSHORT(len, p); + + /* malformed option, delete the whole OPT RR and start again. */ +- if (i + len > rdlen) ++ if (i + 4 + len > rdlen) + { + rdlen = 0; + is_last = 0; +@@ -193,6 +193,8 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l + ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount), + header, plen))) + return plen; ++ if (p + 11 > limit) ++ return plen; /* Too big */ + *p++ = 0; /* empty name */ + PUTSHORT(T_OPT, p); + PUTSHORT(udp_sz, p); /* max packet length, 512 if not given in EDNS0 header */ +@@ -204,6 +206,11 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l + /* Copy back any options */ + if (buff) + { ++ if (p + rdlen > limit) ++ { ++ free(buff); ++ return plen; /* Too big */ ++ } + memcpy(p, buff, rdlen); + free(buff); + p += rdlen; +@@ -217,8 +224,12 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l + /* Add new option */ + if (optno != 0 && replace != 2) + { ++ if (p + 4 > limit) ++ return plen; /* Too big */ + PUTSHORT(optno, p); + PUTSHORT(optlen, p); ++ if (p + optlen > limit) ++ return plen; /* Too big */ + memcpy(p, opt, optlen); + p += optlen; + PUTSHORT(p - datap, lenp); +-- +2.9.5 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-coverity.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-coverity.patch new file mode 100644 index 0000000..87f41a0 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-coverity.patch @@ -0,0 +1,254 @@ +From 7ab5d6bd1f8b018c73341f50a395405dee6873d8 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Wed, 15 Mar 2017 14:26:04 +0100 +Subject: [PATCH] Coverity fixes + +--- + src/dbus.c | 2 +- + src/dhcp-common.c | 2 +- + src/dhcp.c | 4 ++-- + src/dnsmasq.h | 2 +- + src/edns0.c | 2 ++ + src/inotify.c | 9 ++++++--- + src/lease.c | 4 ++-- + src/network.c | 8 ++++---- + src/option.c | 16 +++++++++++----- + src/tftp.c | 2 +- + src/util.c | 2 +- + 11 files changed, 32 insertions(+), 21 deletions(-) + +diff --git a/src/dbus.c b/src/dbus.c +index 2e1a48e..f27ec3e 100644 +--- a/src/dbus.c ++++ b/src/dbus.c +@@ -550,7 +550,7 @@ static DBusMessage *dbus_add_lease(DBusMessage* message) + "Invalid IP address '%s'", ipaddr); + + hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, &hw_type); +- if (hw_type == 0 && hw_len != 0) ++ if (hw_type == 0 && hw_len > 0) + hw_type = ARPHRD_ETHER; + + lease_set_hwaddr(lease, dhcp_chaddr, clid, hw_len, hw_type, +diff --git a/src/dhcp-common.c b/src/dhcp-common.c +index 08528e8..ebf06b6 100644 +--- a/src/dhcp-common.c ++++ b/src/dhcp-common.c +@@ -487,7 +487,7 @@ void bindtodevice(char *device, int fd) + { + struct ifreq ifr; + +- strcpy(ifr.ifr_name, device); ++ strncpy(ifr.ifr_name, device, IF_NAMESIZE-1); + /* only allowed by root. */ + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) == -1 && + errno != EPERM) +diff --git a/src/dhcp.c b/src/dhcp.c +index 10f1fb9..37bb71e 100644 +--- a/src/dhcp.c ++++ b/src/dhcp.c +@@ -246,7 +246,7 @@ void dhcp_packet(time_t now, int pxe_fd) + } + else + { +- strncpy(ifr.ifr_name, bridge->iface, IF_NAMESIZE); ++ strncpy(ifr.ifr_name, bridge->iface, IF_NAMESIZE-1); + break; + } + } +@@ -270,7 +270,7 @@ void dhcp_packet(time_t now, int pxe_fd) + is_relay_reply = 1; + iov.iov_len = sz; + #ifdef HAVE_LINUX_NETWORK +- strncpy(arp_req.arp_dev, ifr.ifr_name, 16); ++ strncpy(arp_req.arp_dev, ifr.ifr_name, IF_NAMESIZE-1); + #endif + } + else +diff --git a/src/dnsmasq.h b/src/dnsmasq.h +index dfd15aa..1179492 100644 +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -180,7 +180,7 @@ struct event_desc { + #define EC_INIT_OFFSET 10 + + /* Trust the compiler dead-code eliminator.... */ +-#define option_bool(x) (((x) < 32) ? daemon->options & (1u << (x)) : daemon->options2 & (1u << ((x) - 32))) ++#define option_bool(x) (((x) < 32) ? daemon->options & (1u << ((x)&0x1F)) : daemon->options2 & (1u << ((x) - 32))) + + #define OPT_BOGUSPRIV 0 + #define OPT_FILTER 1 +diff --git a/src/edns0.c b/src/edns0.c +index c7a101e..d2b514b 100644 +--- a/src/edns0.c ++++ b/src/edns0.c +@@ -263,6 +263,8 @@ static size_t add_dns_client(struct dns_header *header, size_t plen, unsigned ch + encode[8] = 0; + } + } ++ else ++ encode[0] = '\0'; + + return add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMDEVICEID, (unsigned char *)encode, strlen(encode), 0, replace); + } +diff --git a/src/inotify.c b/src/inotify.c +index 603ce9d..fcc0d97 100644 +--- a/src/inotify.c ++++ b/src/inotify.c +@@ -224,17 +224,20 @@ int inotify_check(time_t now) + + if (rc <= 0) + break; ++ else ++ inotify_buffer[rc] = '\0'; + + for (p = inotify_buffer; rc - (p - inotify_buffer) >= (int)sizeof(struct inotify_event); p += sizeof(struct inotify_event) + in->len) + { + in = (struct inotify_event*)p; +- ++ + for (res = daemon->resolv_files; res; res = res->next) +- if (res->wd == in->wd && in->len != 0 && strcmp(res->file, in->name) == 0) ++ if (res->wd == in->wd && in->len != 0 && strncmp(res->file, in->name, NAME_MAX) == 0) + hit = 1; + + /* ignore emacs backups and dotfiles */ +- if (in->len == 0 || ++ if (in->len == 0 || ++ in->len > NAME_MAX+1 || + in->name[in->len - 1] == '~' || + (in->name[0] == '#' && in->name[in->len - 1] == '#') || + in->name[0] == '.') +diff --git a/src/lease.c b/src/lease.c +index 20cac90..9ad106d 100644 +--- a/src/lease.c ++++ b/src/lease.c +@@ -827,9 +827,9 @@ void lease_set_hwaddr(struct dhcp_lease *lease, const unsigned char *hwaddr, + + if (hw_len != lease->hwaddr_len || + hw_type != lease->hwaddr_type || +- (hw_len != 0 && memcmp(lease->hwaddr, hwaddr, hw_len) != 0)) ++ (hw_len > 0 && memcmp(lease->hwaddr, hwaddr, hw_len) != 0)) + { +- if (hw_len != 0) ++ if (hw_len > 0) + memcpy(lease->hwaddr, hwaddr, hw_len); + lease->hwaddr_len = hw_len; + lease->hwaddr_type = hw_type; +diff --git a/src/network.c b/src/network.c +index 6119039..fcd9d8d 100644 +--- a/src/network.c ++++ b/src/network.c +@@ -188,7 +188,7 @@ int loopback_exception(int fd, int family, struct all_addr *addr, char *name) + struct ifreq ifr; + struct irec *iface; + +- strncpy(ifr.ifr_name, name, IF_NAMESIZE); ++ strncpy(ifr.ifr_name, name, IF_NAMESIZE-1); + if (ioctl(fd, SIOCGIFFLAGS, &ifr) != -1 && + ifr.ifr_flags & IFF_LOOPBACK) + { +@@ -1206,7 +1206,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp) + return 0; + + #if defined(SO_BINDTODEVICE) +- if (intname[0] != 0 && ++ if (intname && intname[0] != 0 && + setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1) + return 0; + #endif +@@ -1245,7 +1245,7 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname) + /* may have a suitable one already */ + for (sfd = daemon->sfds; sfd; sfd = sfd->next ) + if (sockaddr_isequal(&sfd->source_addr, addr) && +- strcmp(intname, sfd->interface) == 0 && ++ intname && strcmp(intname, sfd->interface) == 0 && + ifindex == sfd->ifindex) + return sfd; + +@@ -1437,7 +1437,7 @@ void add_update_server(int flags, + serv->flags |= SERV_HAS_DOMAIN; + + if (interface) +- strcpy(serv->interface, interface); ++ strncpy(serv->interface, interface, sizeof(serv->interface)-1); + if (addr) + serv->addr = *addr; + if (source_addr) +diff --git a/src/option.c b/src/option.c +index 5503b79..eb78b1a 100644 +--- a/src/option.c ++++ b/src/option.c +@@ -3929,13 +3929,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma + + case LOPT_HOST_REC: /* --host-record */ + { +- struct host_record *new = opt_malloc(sizeof(struct host_record)); +- memset(new, 0, sizeof(struct host_record)); +- new->ttl = -1; ++ struct host_record *new; + + if (!arg || !(comma = split(arg))) + ret_err(_("Bad host-record")); + ++ new = opt_malloc(sizeof(struct host_record)); ++ memset(new, 0, sizeof(struct host_record)); ++ new->ttl = -1; ++ + while (arg) + { + struct all_addr addr; +@@ -3956,10 +3958,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma + { + int nomem; + char *canon = canonicalise(arg, &nomem); +- struct name_list *nl = opt_malloc(sizeof(struct name_list)); ++ struct name_list *nl; + if (!canon) + ret_err(_("Bad name in host-record")); + ++ nl = opt_malloc(sizeof(struct name_list)); + nl->name = canon; + /* keep order, so that PTR record goes to first name */ + nl->next = NULL; +@@ -4023,7 +4026,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma + !atoi_check8(algo, &new->algo) || + !atoi_check8(digest, &new->digest_type) || + !(new->name = canonicalise_opt(arg))) +- ret_err(_("bad trust anchor")); ++ { ++ free(new); ++ ret_err(_("bad trust anchor")); ++ } + + /* Upper bound on length */ + len = (2*strlen(keyhex))+1; +diff --git a/src/tftp.c b/src/tftp.c +index 5e4a32a..bd8c622 100644 +--- a/src/tftp.c ++++ b/src/tftp.c +@@ -234,7 +234,7 @@ void tftp_request(struct listener *listen, time_t now) + #endif + } + +- strncpy(ifr.ifr_name, name, IF_NAMESIZE); ++ strncpy(ifr.ifr_name, name, IF_NAMESIZE-1); + if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1) + { + mtu = ifr.ifr_mtu; +diff --git a/src/util.c b/src/util.c +index 93b24f5..1a9f228 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -491,7 +491,7 @@ int parse_hex(char *in, unsigned char *out, int maxlen, + int j, bytes = (1 + (r - in))/2; + for (j = 0; j < bytes; j++) + { +- char sav = sav; ++ char sav; + if (j < bytes - 1) + { + sav = in[(j+1)*2]; +-- +2.9.3 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-dhcp-script-log.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-dhcp-script-log.patch new file mode 100644 index 0000000..ac26258 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-dhcp-script-log.patch @@ -0,0 +1,582 @@ +From 87444dc6977b61096127dcdfe87dc6cf2c0167d6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= +Date: Sun, 16 Apr 2017 20:20:08 +0100 +Subject: [PATCH] Capture and log STDOUT and STDERR output from dhcp-script. + +(cherry picked from commit c77fb9d8f09d136fa71bde2469c4fd11cefa6f4a) + +Compile-time check on buffer sizes for leasefile parsing code. + +(cherry picked from commit bf4e62c19e619f7edf8d03d58d33a5752f190bfd) + +Improve error handling with shcp-script "init" mode. + +(cherry picked from commit 3a8b0f6fccf464b1ec6d24c0e00e540ab2b17705) + +Tweak logging introduced in 3a8b0f6fccf464b1ec6d24c0e00e540ab2b17705 + +(cherry picked from commit efff74c1aea14757ce074db28e02671c7f7bb5f5) + +Don't die() on failing to parse lease-script output. + +(cherry picked from commit 05f76dab89d5b879519a4f45b0cccaa1fc3d162d) +--- + man/dnsmasq.8 | 4 +- + src/dhcp-common.c | 16 +++--- + src/dhcp-protocol.h | 4 ++ + src/dnsmasq.c | 8 +++ + src/dnsmasq.h | 54 +++++++++--------- + src/helper.c | 56 +++++++++++++++++- + src/lease.c | 159 +++++++++++++++++++++++++++++++--------------------- + src/log.c | 4 +- + src/rfc3315.c | 2 +- + 9 files changed, 202 insertions(+), 105 deletions(-) + +diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 +index 0521534..97d0a4f 100644 +--- a/man/dnsmasq.8 ++++ b/man/dnsmasq.8 +@@ -1551,8 +1551,8 @@ database. + + + All file descriptors are +-closed except stdin, stdout and stderr which are open to /dev/null +-(except in debug mode). ++closed except stdin, which is open to /dev/null, and stdout and stderr which capture output for logging by dnsmasq. ++(In debug mode, stdio, stdout and stderr file are left as those inherited from the invoker of dnsmasq). + + The script is not invoked concurrently: at most one instance + of the script is ever running (dnsmasq waits for an instance of script to exit +diff --git a/src/dhcp-common.c b/src/dhcp-common.c +index 08528e8..ecc752b 100644 +--- a/src/dhcp-common.c ++++ b/src/dhcp-common.c +@@ -20,11 +20,11 @@ + + void dhcp_common_init(void) + { +- /* These each hold a DHCP option max size 255 +- and get a terminating zero added */ +- daemon->dhcp_buff = safe_malloc(256); +- daemon->dhcp_buff2 = safe_malloc(256); +- daemon->dhcp_buff3 = safe_malloc(256); ++ /* These each hold a DHCP option max size 255 ++ and get a terminating zero added */ ++ daemon->dhcp_buff = safe_malloc(DHCP_BUFF_SZ); ++ daemon->dhcp_buff2 = safe_malloc(DHCP_BUFF_SZ); ++ daemon->dhcp_buff3 = safe_malloc(DHCP_BUFF_SZ); + + /* dhcp_packet is used by v4 and v6, outpacket only by v6 + sizeof(struct dhcp_packet) is as good an initial size as any, +@@ -855,14 +855,14 @@ void log_context(int family, struct dhcp_context *context) + if (context->flags & CONTEXT_RA_STATELESS) + { + if (context->flags & CONTEXT_TEMPLATE) +- strncpy(daemon->dhcp_buff, context->template_interface, 256); ++ strncpy(daemon->dhcp_buff, context->template_interface, DHCP_BUFF_SZ); + else + strcpy(daemon->dhcp_buff, daemon->addrbuff); + } + else + #endif +- inet_ntop(family, start, daemon->dhcp_buff, 256); +- inet_ntop(family, end, daemon->dhcp_buff3, 256); ++ inet_ntop(family, start, daemon->dhcp_buff, DHCP_BUFF_SZ); ++ inet_ntop(family, end, daemon->dhcp_buff3, DHCP_BUFF_SZ); + my_syslog(MS_DHCP | LOG_INFO, + (context->flags & CONTEXT_RA_STATELESS) ? + _("%s stateless on %s%.0s%.0s%s") : +diff --git a/src/dhcp-protocol.h b/src/dhcp-protocol.h +index a31d829..0ea449b 100644 +--- a/src/dhcp-protocol.h ++++ b/src/dhcp-protocol.h +@@ -19,6 +19,10 @@ + #define DHCP_CLIENT_ALTPORT 1068 + #define PXE_PORT 4011 + ++/* These each hold a DHCP option max size 255 ++ and get a terminating zero added */ ++#define DHCP_BUFF_SZ 256 ++ + #define BOOTREQUEST 1 + #define BOOTREPLY 2 + #define DHCP_COOKIE 0x63825363 +diff --git a/src/dnsmasq.c b/src/dnsmasq.c +index 045ec53..9cd4052 100644 +--- a/src/dnsmasq.c ++++ b/src/dnsmasq.c +@@ -1294,6 +1294,7 @@ static void async_event(int pipe, time_t now) + daemon->tcp_pids[i] = 0; + break; + ++#if defined(HAVE_SCRIPT) + case EVENT_KILLED: + my_syslog(LOG_WARNING, _("script process killed by signal %d"), ev.data); + break; +@@ -1307,12 +1308,19 @@ static void async_event(int pipe, time_t now) + daemon->lease_change_command, strerror(ev.data)); + break; + ++ case EVENT_SCRIPT_LOG: ++ my_syslog(MS_SCRIPT | LOG_DEBUG, "%s", msg ? msg : ""); ++ free(msg); ++ msg = NULL; ++ break; ++ + /* necessary for fatal errors in helper */ + case EVENT_USER_ERR: + case EVENT_DIE: + case EVENT_LUA_ERR: + fatal_event(&ev, msg); + break; ++#endif + + case EVENT_REOPEN: + /* Note: this may leave TCP-handling processes with the old file still open. +diff --git a/src/dnsmasq.h b/src/dnsmasq.h +index 1896a64..0cfd3c6 100644 +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -145,30 +145,31 @@ struct event_desc { + int event, data, msg_sz; + }; + +-#define EVENT_RELOAD 1 +-#define EVENT_DUMP 2 +-#define EVENT_ALARM 3 +-#define EVENT_TERM 4 +-#define EVENT_CHILD 5 +-#define EVENT_REOPEN 6 +-#define EVENT_EXITED 7 +-#define EVENT_KILLED 8 +-#define EVENT_EXEC_ERR 9 +-#define EVENT_PIPE_ERR 10 +-#define EVENT_USER_ERR 11 +-#define EVENT_CAP_ERR 12 +-#define EVENT_PIDFILE 13 +-#define EVENT_HUSER_ERR 14 +-#define EVENT_GROUP_ERR 15 +-#define EVENT_DIE 16 +-#define EVENT_LOG_ERR 17 +-#define EVENT_FORK_ERR 18 +-#define EVENT_LUA_ERR 19 +-#define EVENT_TFTP_ERR 20 +-#define EVENT_INIT 21 +-#define EVENT_NEWADDR 22 +-#define EVENT_NEWROUTE 23 +-#define EVENT_TIME_ERR 24 ++#define EVENT_RELOAD 1 ++#define EVENT_DUMP 2 ++#define EVENT_ALARM 3 ++#define EVENT_TERM 4 ++#define EVENT_CHILD 5 ++#define EVENT_REOPEN 6 ++#define EVENT_EXITED 7 ++#define EVENT_KILLED 8 ++#define EVENT_EXEC_ERR 9 ++#define EVENT_PIPE_ERR 10 ++#define EVENT_USER_ERR 11 ++#define EVENT_CAP_ERR 12 ++#define EVENT_PIDFILE 13 ++#define EVENT_HUSER_ERR 14 ++#define EVENT_GROUP_ERR 15 ++#define EVENT_DIE 16 ++#define EVENT_LOG_ERR 17 ++#define EVENT_FORK_ERR 18 ++#define EVENT_LUA_ERR 19 ++#define EVENT_TFTP_ERR 20 ++#define EVENT_INIT 21 ++#define EVENT_NEWADDR 22 ++#define EVENT_NEWROUTE 23 ++#define EVENT_TIME_ERR 24 ++#define EVENT_SCRIPT_LOG 25 + + /* Exit codes. */ + #define EC_GOOD 0 +@@ -242,8 +243,9 @@ struct event_desc { + + /* extra flags for my_syslog, we use a couple of facilities since they are known + not to occupy the same bits as priorities, no matter how syslog.h is set up. */ +-#define MS_TFTP LOG_USER +-#define MS_DHCP LOG_DAEMON ++#define MS_TFTP LOG_USER ++#define MS_DHCP LOG_DAEMON ++#define MS_SCRIPT LOG_MAIL + + struct all_addr { + union { +diff --git a/src/helper.c b/src/helper.c +index 9c37e37..de31383 100644 +--- a/src/helper.c ++++ b/src/helper.c +@@ -14,6 +14,7 @@ + along with this program. If not, see . + */ + ++#include + #include "dnsmasq.h" + + #ifdef HAVE_SCRIPT +@@ -135,7 +136,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) + max_fd != STDIN_FILENO && max_fd != pipefd[0] && + max_fd != event_fd && max_fd != err_fd) + close(max_fd); +- ++ + #ifdef HAVE_LUASCRIPT + if (daemon->luascript) + { +@@ -189,6 +190,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) + unsigned char *buf = (unsigned char *)daemon->namebuff; + unsigned char *end, *extradata, *alloc_buff = NULL; + int is6, err = 0; ++ int pipeout[2]; + + free(alloc_buff); + +@@ -472,16 +474,54 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) + if (!daemon->lease_change_command) + continue; + ++ /* Pipe to capture stdout and stderr from script */ ++ if (!option_bool(OPT_DEBUG) && pipe(pipeout) == -1) ++ continue; ++ + /* possible fork errors are all temporary resource problems */ + while ((pid = fork()) == -1 && (errno == EAGAIN || errno == ENOMEM)) + sleep(2); + + if (pid == -1) +- continue; ++ { ++ if (!option_bool(OPT_DEBUG)) ++ { ++ close(pipeout[0]); ++ close(pipeout[1]); ++ } ++ continue; ++ } + + /* wait for child to complete */ + if (pid != 0) + { ++ if (!option_bool(OPT_DEBUG)) ++ { ++ FILE *fp; ++ ++ close(pipeout[1]); ++ ++ /* Read lines sent to stdout/err by the script and pass them back to be logged */ ++ if (!(fp = fdopen(pipeout[0], "r"))) ++ close(pipeout[0]); ++ else ++ { ++ while (fgets(daemon->packet, daemon->packet_buff_sz, fp)) ++ { ++ /* do not include new lines, log will append them */ ++ size_t len = strlen(daemon->packet); ++ if (len > 0) ++ { ++ --len; ++ if (daemon->packet[len] == '\n') ++ daemon->packet[len] = 0; ++ } ++ send_event(event_fd, EVENT_SCRIPT_LOG, 0, daemon->packet); ++ } ++ fclose(fp); ++ } ++ } ++ + /* reap our children's children, if necessary */ + while (1) + { +@@ -504,6 +544,15 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) + + continue; + } ++ ++ if (!option_bool(OPT_DEBUG)) ++ { ++ /* map stdout/stderr of script to pipeout */ ++ close(pipeout[0]); ++ dup2(pipeout[1], STDOUT_FILENO); ++ dup2(pipeout[1], STDERR_FILENO); ++ close(pipeout[1]); ++ } + + if (data.action != ACTION_TFTP && data.action != ACTION_ARP) + { +@@ -579,7 +628,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) + hostname = NULL; + + my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err); +- } ++ } ++ + /* we need to have the event_fd around if exec fails */ + if ((i = fcntl(event_fd, F_GETFD)) != -1) + fcntl(event_fd, F_SETFD, i | FD_CLOEXEC); +diff --git a/src/lease.c b/src/lease.c +index 20cac90..64047f9 100644 +--- a/src/lease.c ++++ b/src/lease.c +@@ -21,94 +21,62 @@ + static struct dhcp_lease *leases = NULL, *old_leases = NULL; + static int dns_dirty, file_dirty, leases_left; + +-void lease_init(time_t now) ++static int read_leases(time_t now, FILE *leasestream) + { + unsigned long ei; + struct all_addr addr; + struct dhcp_lease *lease; + int clid_len, hw_len, hw_type; +- FILE *leasestream; +- +- leases_left = daemon->dhcp_max; +- +- if (option_bool(OPT_LEASE_RO)) +- { +- /* run " init" once to get the +- initial state of the database. If leasefile-ro is +- set without a script, we just do without any +- lease database. */ +-#ifdef HAVE_SCRIPT +- if (daemon->lease_change_command) +- { +- strcpy(daemon->dhcp_buff, daemon->lease_change_command); +- strcat(daemon->dhcp_buff, " init"); +- leasestream = popen(daemon->dhcp_buff, "r"); +- } +- else ++ int items; ++ char *domain = NULL; ++ ++ *daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0'; ++ ++ /* client-id max length is 255 which is 255*2 digits + 254 colons ++ borrow DNS packet buffer which is always larger than 1000 bytes ++ ++ Check various buffers are big enough for the code below */ ++ ++#if (DHCP_BUFF_SZ < 255) || (MAXDNAME < 64) || (PACKETSZ+MAXDNAME+RRFIXEDSZ < 764) ++# error Buffer size breakage in leasefile parsing. + #endif +- { +- file_dirty = dns_dirty = 0; +- return; +- } + +- } +- else +- { +- /* NOTE: need a+ mode to create file if it doesn't exist */ +- leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+"); +- +- if (!leasestream) +- die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE); +- +- /* a+ mode leaves pointer at end. */ +- rewind(leasestream); +- } +- +- /* client-id max length is 255 which is 255*2 digits + 254 colons +- borrow DNS packet buffer which is always larger than 1000 bytes */ +- if (leasestream) +- while (fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2) == 2) ++ while ((items=fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2)) == 2) + { ++ *daemon->namebuff = *daemon->dhcp_buff = *daemon->packet = '\0'; ++ hw_len = hw_type = clid_len = 0; ++ + #ifdef HAVE_DHCP6 + if (strcmp(daemon->dhcp_buff3, "duid") == 0) + { + daemon->duid_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, 130, NULL, NULL); ++ if (daemon->duid_len < 0) ++ return 0; + daemon->duid = safe_malloc(daemon->duid_len); + memcpy(daemon->duid, daemon->dhcp_buff2, daemon->duid_len); + continue; + } + #endif +- +- ei = atol(daemon->dhcp_buff3); + + if (fscanf(leasestream, " %64s %255s %764s", + daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3) +- break; ++ return 0; + +- clid_len = 0; +- if (strcmp(daemon->packet, "*") != 0) +- clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL); +- +- if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4) && +- (lease = lease4_allocate(addr.addr.addr4))) ++ if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4)) + { ++ if ((lease = lease4_allocate(addr.addr.addr4))) ++ domain = get_domain(lease->addr); ++ + hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type); + /* For backwards compatibility, no explict MAC address type means ether. */ + if (hw_type == 0 && hw_len != 0) + hw_type = ARPHRD_ETHER; +- +- lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet, +- hw_len, hw_type, clid_len, now, 0); +- +- if (strcmp(daemon->dhcp_buff, "*") != 0) +- lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain(lease->addr), NULL); + } + #ifdef HAVE_DHCP6 + else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6)) + { + char *s = daemon->dhcp_buff2; + int lease_type = LEASE_NA; +- int iaid; + + if (s[0] == 'T') + { +@@ -116,23 +84,30 @@ void lease_init(time_t now) + s++; + } + +- iaid = strtoul(s, NULL, 10); +- + if ((lease = lease6_allocate(&addr.addr.addr6, lease_type))) + { +- lease_set_hwaddr(lease, NULL, (unsigned char *)daemon->packet, 0, 0, clid_len, now, 0); +- lease_set_iaid(lease, iaid); +- if (strcmp(daemon->dhcp_buff, "*") != 0) +- lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain6((struct in6_addr *)lease->hwaddr), NULL); ++ lease_set_iaid(lease, strtoul(s, NULL, 10)); ++ domain = get_domain6((struct in6_addr *)lease->hwaddr); + } + } + #endif + else +- break; ++ return 0; + + if (!lease) + die (_("too many stored leases"), NULL, EC_MISC); +- ++ ++ if (strcmp(daemon->packet, "*") != 0) ++ clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL); ++ ++ lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet, ++ hw_len, hw_type, clid_len, now, 0); ++ ++ if (strcmp(daemon->dhcp_buff, "*") != 0) ++ lease_set_hostname(lease, daemon->dhcp_buff, 0, domain, NULL); ++ ++ ei = atol(daemon->dhcp_buff3); ++ + #ifdef HAVE_BROKEN_RTC + if (ei != 0) + lease->expires = (time_t)ei + now; +@@ -148,7 +123,62 @@ void lease_init(time_t now) + /* set these correctly: the "old" events are generated later from + the startup synthesised SIGHUP. */ + lease->flags &= ~(LEASE_NEW | LEASE_CHANGED); ++ ++ *daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0'; + } ++ ++ return (items == 0 || items == EOF); ++} ++ ++void lease_init(time_t now) ++{ ++ FILE *leasestream; ++ ++ leases_left = daemon->dhcp_max; ++ ++ if (option_bool(OPT_LEASE_RO)) ++ { ++ /* run " init" once to get the ++ initial state of the database. If leasefile-ro is ++ set without a script, we just do without any ++ lease database. */ ++#ifdef HAVE_SCRIPT ++ if (daemon->lease_change_command) ++ { ++ strcpy(daemon->dhcp_buff, daemon->lease_change_command); ++ strcat(daemon->dhcp_buff, " init"); ++ leasestream = popen(daemon->dhcp_buff, "r"); ++ } ++ else ++#endif ++ { ++ file_dirty = dns_dirty = 0; ++ return; ++ } ++ ++ } ++ else ++ { ++ /* NOTE: need a+ mode to create file if it doesn't exist */ ++ leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+"); ++ ++ if (!leasestream) ++ die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE); ++ ++ /* a+ mode leaves pointer at end. */ ++ rewind(leasestream); ++ } ++ ++ if (leasestream) ++ { ++ if (!read_leases(now, leasestream)) ++ my_syslog(MS_DHCP | LOG_ERR, _("failed to parse lease database, invalid line: %s %s %s %s ..."), ++ daemon->dhcp_buff3, daemon->dhcp_buff2, ++ daemon->namebuff, daemon->dhcp_buff); ++ ++ if (ferror(leasestream)) ++ die(_("failed to read lease file %s: %s"), daemon->lease_file, EC_FILE); ++ } + + #ifdef HAVE_SCRIPT + if (!daemon->lease_stream) +@@ -162,6 +192,7 @@ void lease_init(time_t now) + errno = ENOENT; + else if (WEXITSTATUS(rc) == 126) + errno = EACCES; ++ + die(_("cannot run lease-init script %s: %s"), daemon->lease_change_command, EC_FILE); + } + +diff --git a/src/log.c b/src/log.c +index 8e66629..5fc860b 100644 +--- a/src/log.c ++++ b/src/log.c +@@ -288,7 +288,9 @@ void my_syslog(int priority, const char *format, ...) + func = "-tftp"; + else if ((LOG_FACMASK & priority) == MS_DHCP) + func = "-dhcp"; +- ++ else if ((LOG_FACMASK & priority) == MS_SCRIPT) ++ func = "-script"; ++ + #ifdef LOG_PRI + priority = LOG_PRI(priority); + #else +diff --git a/src/rfc3315.c b/src/rfc3315.c +index 3f4d69c..a3715cd 100644 +--- a/src/rfc3315.c ++++ b/src/rfc3315.c +@@ -1975,7 +1975,7 @@ static void log6_packet(struct state *state, char *type, struct in6_addr *addr, + + if (addr) + { +- inet_ntop(AF_INET6, addr, daemon->dhcp_buff2, 255); ++ inet_ntop(AF_INET6, addr, daemon->dhcp_buff2, DHCP_BUFF_SZ - 1); + strcat(daemon->dhcp_buff2, " "); + } + else +-- +2.9.3 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-dns-sleep-resume.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-dns-sleep-resume.patch new file mode 100644 index 0000000..4271d8d --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-dns-sleep-resume.patch @@ -0,0 +1,119 @@ +From 2675f2061525bc954be14988d64384b74aa7bf8b Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +Date: Sun, 28 Aug 2016 20:44:05 +0100 +Subject: [PATCH] Handle binding upstream servers to an interface + (--server=1.2.3.4@eth0) when the named interface is destroyed and recreated + in the kernel. + +--- + CHANGELOG | 5 +++++ + src/dnsmasq.h | 1 + + src/network.c | 31 +++++++++++++++++++++++++++++-- + 3 files changed, 35 insertions(+), 2 deletions(-) + +diff --git a/src/dnsmasq.h b/src/dnsmasq.h +index 27385a9..f239ce5 100644 +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -488,6 +488,7 @@ struct serverfd { + int fd; + union mysockaddr source_addr; + char interface[IF_NAMESIZE+1]; ++ unsigned int ifindex, used; + struct serverfd *next; + }; + +diff --git a/src/network.c b/src/network.c +index e7722fd..ddf8d31 100644 +--- a/src/network.c ++++ b/src/network.c +@@ -1204,6 +1204,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp) + static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname) + { + struct serverfd *sfd; ++ unsigned int ifindex = 0; + int errsave; + + /* when using random ports, servers which would otherwise use +@@ -1224,11 +1225,15 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname) + return NULL; + #endif + } ++ ++ if (intname && strlen(intname) != 0) ++ ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */ + + /* may have a suitable one already */ + for (sfd = daemon->sfds; sfd; sfd = sfd->next ) + if (sockaddr_isequal(&sfd->source_addr, addr) && +- strcmp(intname, sfd->interface) == 0) ++ strcmp(intname, sfd->interface) == 0 && ++ ifindex == sfd->ifindex) + return sfd; + + /* need to make a new one. */ +@@ -1250,11 +1255,13 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname) + errno = errsave; + return NULL; + } +- ++ + strcpy(sfd->interface, intname); + sfd->source_addr = *addr; + sfd->next = daemon->sfds; ++ sfd->ifindex = ifindex; + daemon->sfds = sfd; ++ + return sfd; + } + +@@ -1429,12 +1436,16 @@ void check_servers(void) + { + struct irec *iface; + struct server *serv; ++ struct serverfd *sfd, *tmp, **up; + int port = 0, count; + + /* interface may be new since startup */ + if (!option_bool(OPT_NOWILD)) + enumerate_interfaces(0); + ++ for (sfd = daemon->sfds; sfd; sfd = sfd->next) ++ sfd->used = 0; ++ + #ifdef HAVE_DNSSEC + /* Disable DNSSEC validation when using server=/domain/.... servers + unless there's a configured trust anchor. */ +@@ -1505,6 +1516,8 @@ void check_servers(void) + serv->flags |= SERV_MARK; + continue; + } ++ ++ serv->sfd->used = 1; + } + + if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS)) +@@ -1547,6 +1560,20 @@ void check_servers(void) + if (count - 1 > SERVERS_LOGGED) + my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1); + ++ /* Remove unused sfds */ ++ for (sfd = daemon->sfds, up = &daemon->sfds; sfd; sfd = tmp) ++ { ++ tmp = sfd->next; ++ if (!sfd->used) ++ { ++ *up = sfd->next; ++ close(sfd->fd); ++ free(sfd); ++ } ++ else ++ up = &sfd->next; ++ } ++ + cleanup_servers(); + } + +-- +2.7.4 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-file_offset32.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-file_offset32.patch new file mode 100644 index 0000000..f06996d --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-file_offset32.patch @@ -0,0 +1,12 @@ +diff --git a/src/helper.c b/src/helper.c +index de31383..a843b41 100644 +--- a/src/helper.c ++++ b/src/helper.c +@@ -14,7 +14,6 @@ + along with this program. If not, see . + */ + +-#include + #include "dnsmasq.h" + + #ifdef HAVE_SCRIPT diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-fix-crash-dns-resume.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-fix-crash-dns-resume.patch new file mode 100644 index 0000000..2857de0 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-fix-crash-dns-resume.patch @@ -0,0 +1,29 @@ +From 16800ea072dd0cdf14d951c4bb8d2808b3dfe53d Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Tue, 30 Aug 2016 23:07:06 +0100 +Subject: [PATCH] Fix crash introduced in + 2675f2061525bc954be14988d64384b74aa7bf8b + +--- + src/network.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/network.c b/src/network.c +index ddf8d31..d87d08f 100644 +--- a/src/network.c ++++ b/src/network.c +@@ -1516,8 +1516,9 @@ void check_servers(void) + serv->flags |= SERV_MARK; + continue; + } +- +- serv->sfd->used = 1; ++ ++ if (serv->sfd) ++ serv->sfd->used = 1; + } + + if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS)) +-- +2.9.3 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-fix-dhcp-option-arrangements.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-fix-dhcp-option-arrangements.patch new file mode 100644 index 0000000..7155b0f --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-fix-dhcp-option-arrangements.patch @@ -0,0 +1,49 @@ +From 591ed1e90503817938ccf5f127e677a8dd48b6d8 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 11 Jul 2016 18:18:42 +0100 +Subject: [PATCH] Fix bad behaviour with some DHCP option arrangements. + +The check that there's enough space to store the DHCP agent-id +at the end of the packet could succeed when it should fail +if the END option is in either of the oprion-overload areas. +That could overwrite legit options in the request and cause +bad behaviour. It's highly unlikely that any sane DHCP client +would trigger this bug, and it's never been seen, but this +fixes the problem. + +Also fix off-by-one in bounds checking of option processing. +Worst case scenario on that is a read one byte beyond the +end off a buffer with a crafted packet, and maybe therefore +a SIGV crash if the memory after the buffer is not mapped. + +Thanks to Timothy Becker for spotting these. +--- + src/rfc2131.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/rfc2131.c b/src/rfc2131.c +index b7c167e..8b99d4b 100644 +--- a/src/rfc2131.c ++++ b/src/rfc2131.c +@@ -186,7 +186,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, + be enough free space at the end of the packet to copy the option. */ + unsigned char *sopt; + unsigned int total = option_len(opt) + 2; +- unsigned char *last_opt = option_find(mess, sz, OPTION_END, 0); ++ unsigned char *last_opt = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char *)mess) + sz, ++ OPTION_END, 0); + if (last_opt && last_opt < end - total) + { + end -= total; +@@ -1606,7 +1607,7 @@ static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt + { + while (1) + { +- if (p > end) ++ if (p >= end) + return NULL; + else if (*p == OPTION_END) + return opt == OPTION_END ? p : NULL; +-- +2.9.3 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-gita3303e196.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-gita3303e196.patch new file mode 100644 index 0000000..a437848 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-gita3303e196.patch @@ -0,0 +1,45 @@ +From 2c1aec1e979a209eb2f2b035314a8c973b4ac269 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Thu, 7 Sep 2017 20:45:00 +0100 +Subject: [PATCH 7/9] Don't return arcount=1 if EDNS0 RR won't fit in the + packet. + + Omitting the EDNS0 RR but setting arcount gives a malformed packet. + Also, don't accept UDP packet size less than 512 in recieved EDNS0. +--- + src/edns0.c | 5 ++++- + src/forward.c | 2 ++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/edns0.c b/src/edns0.c +index 5bdc133..a8d0167 100644 +--- a/src/edns0.c ++++ b/src/edns0.c +@@ -221,7 +221,10 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l + free(buff); + p += rdlen; + } +- header->arcount = htons(ntohs(header->arcount) + 1); ++ ++ /* Only bump arcount if RR is going to fit */ ++ if (((ssize_t)optlen) <= (limit - (p + 4))) ++ header->arcount = htons(ntohs(header->arcount) + 1); + } + + if (((ssize_t)optlen) > (limit - (p + 4))) +diff --git a/src/forward.c b/src/forward.c +index 9b464d3..0f8f462 100644 +--- a/src/forward.c ++++ b/src/forward.c +@@ -1408,6 +1408,8 @@ void receive_query(struct listener *listen, time_t now) + defaults to 512 */ + if (udp_size > daemon->edns_pktsz) + udp_size = daemon->edns_pktsz; ++ else if (udp_size < PACKETSZ) ++ udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */ + } + + #ifdef HAVE_AUTH +-- +2.9.5 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-inotify.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-inotify.patch new file mode 100644 index 0000000..6387d3f --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-inotify.patch @@ -0,0 +1,14 @@ +diff --git a/src/dnsmasq.c b/src/dnsmasq.c +index e1d3bbd..99e5437 100644 +--- a/src/dnsmasq.c ++++ b/src/dnsmasq.c +@@ -358,7 +358,8 @@ int main (int argc, char **argv) + } + + #ifdef HAVE_INOTIFY +- if (daemon->port != 0 || daemon->dhcp || daemon->doing_dhcp6) ++ if ((daemon->port != 0 || daemon->dhcp || daemon->doing_dhcp6) ++ && (!option_bool(OPT_NO_RESOLV) || daemon->dynamic_dirs)) + inotify_dnsmasq_init(); + else + daemon->inotifyfd = -1; diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-label-man.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-label-man.patch new file mode 100644 index 0000000..74514bd --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-label-man.patch @@ -0,0 +1,36 @@ +From 6eaafb18e56928881bae371ba8bb05ee93f55d54 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= +Date: Tue, 14 Mar 2017 15:24:58 +0100 +Subject: [PATCH 2/2] Document real behaviour of labels with --interface + +--- + man/dnsmasq.8 | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 +index 523c823..6e93cf1 100644 +--- a/man/dnsmasq.8 ++++ b/man/dnsmasq.8 +@@ -203,12 +203,14 @@ or + options are given dnsmasq listens on all available interfaces except any + given in + .B \--except-interface +-options. IP alias interfaces (eg "eth1:0") cannot be used with +-.B --interface ++options. IP alias interface names (eg "eth1:0") can be used only in ++.B \--bind-interfaces + or +-.B --except-interface +-options, use --listen-address instead. A simple wildcard, consisting +-of a trailing '*', can be used in ++.B \--bind-dynamic ++mode. Use ++.B \--listen-address ++in the default mode instead. A simple wildcard, consisting of a trailing '*', ++can be used in + .B \--interface + and + .B \--except-interface +-- +2.9.3 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-label-warning.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-label-warning.patch new file mode 100644 index 0000000..7c156ab --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-label-warning.patch @@ -0,0 +1,93 @@ +From c3d10a1132ada7baa80914f61abb720f94400465 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= +Date: Tue, 14 Mar 2017 15:23:22 +0100 +Subject: [PATCH 1/2] Warn when using label in default mode + +--- + src/dnsmasq.c | 2 ++ + src/dnsmasq.h | 3 ++- + src/network.c | 13 +++++++++++++ + 3 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/src/dnsmasq.c b/src/dnsmasq.c +index 456b0e8..d2cc7cc 100644 +--- a/src/dnsmasq.c ++++ b/src/dnsmasq.c +@@ -771,6 +771,8 @@ int main (int argc, char **argv) + + if (option_bool(OPT_NOWILD)) + warn_bound_listeners(); ++ else if (!option_bool(OPT_CLEVERBIND)) ++ warn_wild_labels(); + + warn_int_names(); + +diff --git a/src/dnsmasq.h b/src/dnsmasq.h +index a27fbc1..6b44e53 100644 +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -522,7 +522,7 @@ struct ipsets { + struct irec { + union mysockaddr addr; + struct in_addr netmask; /* only valid for IPv4 */ +- int tftp_ok, dhcp_ok, mtu, done, warned, dad, dns_auth, index, multicast_done, found; ++ int tftp_ok, dhcp_ok, mtu, done, warned, dad, dns_auth, index, multicast_done, found, label; + char *name; + struct irec *next; + }; +@@ -1252,6 +1252,7 @@ int enumerate_interfaces(int reset); + void create_wildcard_listeners(void); + void create_bound_listeners(int die); + void warn_bound_listeners(void); ++void warn_wild_labels(void); + void warn_int_names(void); + int is_dad_listeners(void); + int iface_check(int family, struct all_addr *addr, char *name, int *auth_dns); +diff --git a/src/network.c b/src/network.c +index eb41624..e5ceb76 100644 +--- a/src/network.c ++++ b/src/network.c +@@ -244,6 +244,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label, + int tftp_ok = !!option_bool(OPT_TFTP); + int dhcp_ok = 1; + int auth_dns = 0; ++ int is_label = 0; + #if defined(HAVE_DHCP) || defined(HAVE_TFTP) + struct iname *tmp; + #endif +@@ -264,6 +265,8 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label, + + if (!label) + label = ifr.ifr_name; ++ else ++ is_label = strcmp(label, ifr.ifr_name); + + /* maintain a list of all addresses on all interfaces for --local-service option */ + if (option_bool(OPT_LOCAL_SERVICE)) +@@ -482,6 +485,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label, + iface->found = 1; + iface->done = iface->multicast_done = iface->warned = 0; + iface->index = if_index; ++ iface->label = is_label; + if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1))) + { + strcpy(iface->name, ifr.ifr_name); +@@ -1034,6 +1038,15 @@ void warn_bound_listeners(void) + my_syslog(LOG_WARNING, _("LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)")); + } + ++void warn_wild_labels(void) ++{ ++ struct irec *iface; ++ ++ for (iface = daemon->interfaces; iface; iface = iface->next) ++ if (iface->found && iface->name && iface->label) ++ my_syslog(LOG_WARNING, _("warning: using interface %s instead"), iface->name); ++} ++ + void warn_int_names(void) + { + struct interface_name *intname; +-- +2.9.3 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-misc-cleanups.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-misc-cleanups.patch new file mode 100644 index 0000000..e8a2132 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-misc-cleanups.patch @@ -0,0 +1,63 @@ +From 3947ab0069e443e72debe26379b8517fac8f6e41 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Mon, 25 Sep 2017 20:19:55 +0100 +Subject: [PATCH 8/9] Misc code cleanups arising from Google analysis. + No security impleications or CVEs. + +--- + src/edns0.c | 2 +- + src/rfc1035.c | 4 +++- + src/rfc2131.c | 2 +- + 3 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/edns0.c b/src/edns0.c +index a8d0167..0552d38 100644 +--- a/src/edns0.c ++++ b/src/edns0.c +@@ -159,7 +159,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l + /* delete option if we're to replace it. */ + p -= 4; + rdlen -= len + 4; +- memcpy(p, p+len+4, rdlen - i); ++ memmove(p, p+len+4, rdlen - i); + PUTSHORT(rdlen, lenp); + lenp -= 2; + } +diff --git a/src/rfc1035.c b/src/rfc1035.c +index 78410d6..917bac2 100644 +--- a/src/rfc1035.c ++++ b/src/rfc1035.c +@@ -37,7 +37,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, + /* end marker */ + { + /* check that there are the correct no of bytes after the name */ +- if (!CHECK_LEN(header, p, plen, extrabytes)) ++ if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes)) + return 0; + + if (isExtract) +@@ -485,6 +485,8 @@ static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header * + { + unsigned int i, len = *p1; + unsigned char *p2 = p1; ++ if ((p1 + len - p) >= rdlen) ++ return 0; /* bad packet */ + /* make counted string zero-term and sanitise */ + for (i = 0; i < len; i++) + { +diff --git a/src/rfc2131.c b/src/rfc2131.c +index 75893a6..71d5846 100644 +--- a/src/rfc2131.c ++++ b/src/rfc2131.c +@@ -155,7 +155,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, + for (offset = 0; offset < (len - 5); offset += elen + 5) + { + elen = option_uint(opt, offset + 4 , 1); +- if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA) ++ if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA && offset + elen + 5 <= len) + { + unsigned char *x = option_ptr(opt, offset + 5); + unsigned char *y = option_ptr(opt, offset + elen + 5); +-- +2.9.5 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-pftables.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-pftables.patch new file mode 100644 index 0000000..fffd3a2 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-pftables.patch @@ -0,0 +1,149 @@ +From 396750cef533cf72c7e6a72e47a9c93e2e431cb7 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Sat, 13 Aug 2016 22:34:11 +0100 +Subject: [PATCH] Refactor openBSD pftables code to remove blatant copyright + violation. + +--- + src/tables.c | 90 +++++++++++++++++++++--------------------------------------- + 1 file changed, 32 insertions(+), 58 deletions(-) + +diff --git a/src/tables.c b/src/tables.c +index aae1252..4fa3487 100644 +--- a/src/tables.c ++++ b/src/tables.c +@@ -53,52 +53,6 @@ static char *pfr_strerror(int errnum) + } + } + +-static int pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) +-{ +- struct pfioc_table io; +- +- if (size < 0 || (size && tbl == NULL)) +- { +- errno = EINVAL; +- return (-1); +- } +- bzero(&io, sizeof io); +- io.pfrio_flags = flags; +- io.pfrio_buffer = tbl; +- io.pfrio_esize = sizeof(*tbl); +- io.pfrio_size = size; +- if (ioctl(dev, DIOCRADDTABLES, &io)) +- return (-1); +- if (nadd != NULL) +- *nadd = io.pfrio_nadd; +- return (0); +-} +- +-static int fill_addr(const struct all_addr *ipaddr, int flags, struct pfr_addr* addr) { +- if ( !addr || !ipaddr) +- { +- my_syslog(LOG_ERR, _("error: fill_addr missused")); +- return -1; +- } +- bzero(addr, sizeof(*addr)); +-#ifdef HAVE_IPV6 +- if (flags & F_IPV6) +- { +- addr->pfra_af = AF_INET6; +- addr->pfra_net = 0x80; +- memcpy(&(addr->pfra_ip6addr), &(ipaddr->addr), sizeof(struct in6_addr)); +- } +- else +-#endif +- { +- addr->pfra_af = AF_INET; +- addr->pfra_net = 0x20; +- addr->pfra_ip4addr.s_addr = ipaddr->addr.addr4.s_addr; +- } +- return 1; +-} +- +-/*****************************************************************************/ + + void ipset_init(void) + { +@@ -111,14 +65,13 @@ void ipset_init(void) + } + + int add_to_ipset(const char *setname, const struct all_addr *ipaddr, +- int flags, int remove) ++ int flags, int remove) + { + struct pfr_addr addr; + struct pfioc_table io; + struct pfr_table table; +- int n = 0, rc = 0; + +- if ( dev == -1 ) ++ if (dev == -1) + { + my_syslog(LOG_ERR, _("warning: no opened pf devices %s"), pf_device); + return -1; +@@ -126,31 +79,52 @@ int add_to_ipset(const char *setname, const struct all_addr *ipaddr, + + bzero(&table, sizeof(struct pfr_table)); + table.pfrt_flags |= PFR_TFLAG_PERSIST; +- if ( strlen(setname) >= PF_TABLE_NAME_SIZE ) ++ if (strlen(setname) >= PF_TABLE_NAME_SIZE) + { + my_syslog(LOG_ERR, _("error: cannot use table name %s"), setname); + errno = ENAMETOOLONG; + return -1; + } + +- if ( strlcpy(table.pfrt_name, setname, +- sizeof(table.pfrt_name)) >= sizeof(table.pfrt_name)) ++ if (strlcpy(table.pfrt_name, setname, ++ sizeof(table.pfrt_name)) >= sizeof(table.pfrt_name)) + { + my_syslog(LOG_ERR, _("error: cannot strlcpy table name %s"), setname); + return -1; + } + +- if ((rc = pfr_add_tables(&table, 1, &n, 0))) ++ bzero(&io, sizeof io); ++ io.pfrio_flags = 0; ++ io.pfrio_buffer = &table; ++ io.pfrio_esize = sizeof(table); ++ io.pfrio_size = 1; ++ if (ioctl(dev, DIOCRADDTABLES, &io)) + { +- my_syslog(LOG_WARNING, _("warning: pfr_add_tables: %s(%d)"), +- pfr_strerror(errno),rc); ++ my_syslog(LOG_WARNING, _("IPset: error:%s"), pfr_strerror(errno)); ++ + return -1; + } ++ + table.pfrt_flags &= ~PFR_TFLAG_PERSIST; +- if (n) ++ if (io.pfrio_nadd) + my_syslog(LOG_INFO, _("info: table created")); +- +- fill_addr(ipaddr,flags,&addr); ++ ++ bzero(&addr, sizeof(addr)); ++#ifdef HAVE_IPV6 ++ if (flags & F_IPV6) ++ { ++ addr.pfra_af = AF_INET6; ++ addr.pfra_net = 0x80; ++ memcpy(&(addr.pfra_ip6addr), &(ipaddr->addr), sizeof(struct in6_addr)); ++ } ++ else ++#endif ++ { ++ addr.pfra_af = AF_INET; ++ addr.pfra_net = 0x20; ++ addr.pfra_ip4addr.s_addr = ipaddr->addr.addr4.s_addr; ++ } ++ + bzero(&io, sizeof(io)); + io.pfrio_flags = 0; + io.pfrio_table = table; +-- +2.9.3 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-underflow.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-underflow.patch new file mode 100644 index 0000000..ac8188e --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-underflow.patch @@ -0,0 +1,74 @@ +From d4f2e0b8d8f0b5daa0d468f62a0d5f1df58ac325 Mon Sep 17 00:00:00 2001 +From: Doran Moppert +Date: Tue, 26 Sep 2017 14:48:20 +0930 +Subject: [PATCH 9/9] google patch hand-applied + +--- + src/edns0.c | 10 +++++----- + src/forward.c | 4 ++++ + src/rfc1035.c | 6 ++++-- + 3 files changed, 13 insertions(+), 7 deletions(-) + +diff --git a/src/edns0.c b/src/edns0.c +index 0552d38..bec4a36 100644 +--- a/src/edns0.c ++++ b/src/edns0.c +@@ -212,11 +212,11 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l + /* Copy back any options */ + if (buff) + { +- if (p + rdlen > limit) +- { +- free(buff); +- return plen; /* Too big */ +- } ++ if (p + rdlen > limit) ++ { ++ free(buff); ++ return plen; /* Too big */ ++ } + memcpy(p, buff, rdlen); + free(buff); + p += rdlen; +diff --git a/src/forward.c b/src/forward.c +index 0f8f462..a729c06 100644 +--- a/src/forward.c ++++ b/src/forward.c +@@ -1412,6 +1412,10 @@ void receive_query(struct listener *listen, time_t now) + udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */ + } + ++ // Make sure the udp size is not smaller than the incoming message so that we ++ // do not underflow ++ if (udp_size < n) udp_size = n; ++ + #ifdef HAVE_AUTH + if (auth_dns) + { +diff --git a/src/rfc1035.c b/src/rfc1035.c +index 917bac2..ae65702 100644 +--- a/src/rfc1035.c ++++ b/src/rfc1035.c +@@ -1182,8 +1182,8 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int + va_end(ap); /* clean up variable argument pointer */ + + j = p - sav - 2; +- /* this has already been checked against limit before */ +- PUTSHORT(j, sav); /* Now, store real RDLength */ ++ /* this has already been checked against limit before */ ++ PUTSHORT(j, sav); /* Now, store real RDLength */ + + /* check for overflow of buffer */ + if (limit && ((unsigned char *)limit - p) < 0) +@@ -1243,6 +1243,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, + int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1; + struct mx_srv_record *rec; + size_t len; ++ // Make sure we do not underflow here too. ++ if (qlen > (limit - ((char *)header))) return 0; + + if (ntohs(header->ancount) != 0 || + ntohs(header->nscount) != 0 || +-- +2.9.5 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-warning-fixes.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-warning-fixes.patch new file mode 100644 index 0000000..8b0bea8 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-2.76-warning-fixes.patch @@ -0,0 +1,60 @@ +From 13dee6f49e1d035b8069947be84ee8da2af0c420 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Tue, 28 Feb 2017 16:51:58 +0000 +Subject: [PATCH] Compilation warning fixes. + +--- + src/dbus.c | 9 ++++----- + src/option.c | 3 ++- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/dbus.c b/src/dbus.c +index 7e0d342..2e1a48e 100644 +--- a/src/dbus.c ++++ b/src/dbus.c +@@ -549,17 +549,16 @@ static DBusMessage *dbus_add_lease(DBusMessage* message) + return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS, + "Invalid IP address '%s'", ipaddr); + +- hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, +- &hw_type); ++ hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, &hw_type); + if (hw_type == 0 && hw_len != 0) + hw_type = ARPHRD_ETHER; +- +- lease_set_hwaddr(lease, dhcp_chaddr, clid, hw_len, hw_type, ++ ++ lease_set_hwaddr(lease, dhcp_chaddr, clid, hw_len, hw_type, + clid_len, now, 0); + lease_set_expires(lease, expires, now); + if (hostname_len != 0) + lease_set_hostname(lease, hostname, 0, get_domain(lease->addr), NULL); +- ++ + lease_update_file(now); + lease_update_dns(0); + +diff --git a/src/option.c b/src/option.c +index 4a5ef5f..e03b1e3 100644 +--- a/src/option.c ++++ b/src/option.c +@@ -4089,7 +4089,7 @@ static void read_file(char *file, FILE *f, int hard_opt) + { + int white, i; + volatile int option = (hard_opt == LOPT_REV_SERV) ? 0 : hard_opt; +- char *errmess, *p, *arg = NULL, *start; ++ char *errmess, *p, *arg, *start; + size_t len; + + /* Memory allocation failure longjmps here if mem_recover == 1 */ +@@ -4100,6 +4100,7 @@ static void read_file(char *file, FILE *f, int hard_opt) + mem_recover = 1; + } + ++ arg = NULL; + lineno++; + errmess = NULL; + +-- +2.9.3 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-update-ipv6-leases-from-config.patch b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-update-ipv6-leases-from-config.patch new file mode 100644 index 0000000..1304435 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq-update-ipv6-leases-from-config.patch @@ -0,0 +1,83 @@ +From 1a91b72146893dab1cca1354dd3b0a8fa74d6b55 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Tue, 18 Oct 2016 13:07:56 -0400 +Subject: WRS: Patch22: dnsmasq-update-ipv6-leases-from-config.patch + +--- + src/lease.c | 53 +++++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 43 insertions(+), 10 deletions(-) + +diff --git a/src/lease.c b/src/lease.c +index 69e698c..bc56c47 100644 +--- a/src/lease.c ++++ b/src/lease.c +@@ -210,6 +210,18 @@ void lease_init(time_t now) + dns_dirty = 1; + } + ++static int lease_match_config_addr(struct dhcp_lease *lease, struct dhcp_config *config) ++{ ++ if (!(lease->flags & (LEASE_TA | LEASE_NA)) && (config->flags & CONFIG_ADDR)) ++ return (lease->addr.s_addr == config->addr.s_addr); ++#ifdef HAVE_DHCP6 ++ else if ((lease->flags & (LEASE_TA | LEASE_NA)) && (config->flags & CONFIG_ADDR6)) ++ return IN6_ARE_ADDR_EQUAL(&config->addr6, &lease->addr6); ++#endif ++ else ++ return 0; ++} ++ + void lease_update_from_configs(void) + { + /* changes to the config may change current leases. */ +@@ -218,16 +230,37 @@ void lease_update_from_configs(void) + struct dhcp_config *config; + char *name; + +- for (lease = leases; lease; lease = lease->next) +- if (lease->flags & (LEASE_TA | LEASE_NA)) +- continue; +- else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len, +- lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) && +- (config->flags & CONFIG_NAME) && +- (!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr)) +- lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL); +- else if ((name = host_from_dns(lease->addr))) +- lease_set_hostname(lease, name, 1, get_domain(lease->addr), NULL); /* updates auth flag only */ ++ for (lease = leases; lease; lease = lease->next) { ++ if (lease->flags & LEASE_TA) ++ continue; /* we do not update temporary ipv6 leases */ ++ ++ config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len, ++ (lease->hwaddr_len > 0 ? lease->hwaddr : NULL), ++ lease->hwaddr_len, lease->hwaddr_type, NULL); ++ if (config) ++ { ++ if ((!(config->flags & (CONFIG_ADDR | CONFIG_ADDR6))) || ++ lease_match_config_addr(lease, config)) ++ { ++ /* ++ * Either we matched on a config that doesn't have an address in ++ * which case we'll just use the hostname, or we matched on a ++ * config that has the same IP address. ++ */ ++ if (!(lease->flags & (LEASE_TA | LEASE_NA))) ++ lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL); ++#ifdef HAVE_DHCP6 ++ else ++ lease_set_hostname(lease, config->hostname, 1, get_domain6(&lease->addr6), NULL); ++#endif ++ continue; /* lease updated; move on to next lease */ ++ } ++ } ++ ++ /* attempt to find a matching DNS cache entry for an IPv4 entry */ ++ if (!(lease->flags & (LEASE_TA | LEASE_NA)) && (name = host_from_dns(lease->addr))) ++ lease_set_hostname(lease, name, 1, get_domain(lease->addr), NULL); /* updates auth flag only */ ++ } + } + + static void ourprintf(int *errp, char *format, ...) +-- +2.7.4 + diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq.service b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq.service new file mode 100644 index 0000000..572db30 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq/stx/dnsmasq.service @@ -0,0 +1,9 @@ +[Unit] +Description=DNS caching server. +After=network.target + +[Service] +ExecStart=/usr/bin/dnsmasq -k + +[Install] +WantedBy=multi-user.target diff --git a/meta-stx/recipes-support/dnsmasq/dnsmasq_2.76.bb b/meta-stx/recipes-support/dnsmasq/dnsmasq_2.76.bb new file mode 100644 index 0000000..3258f44 --- /dev/null +++ b/meta-stx/recipes-support/dnsmasq/dnsmasq_2.76.bb @@ -0,0 +1,135 @@ +SUMMARY = "Lightweight, easy to configure DNS forwarder and DHCP server" +DESCRIPTION = "\ +Dnsmasq is lightweight, easy to configure DNS forwarder and DHCP server. \ +It is designed to provide DNS and, optionally, DHCP, to a small network. \ +It can serve the names of local machines which are not in the global \ +DNS. The DHCP server integrates with the DNS server and allows machines \ +with DHCP-allocated addresses to appear in the DNS with names configured \ +either in each host or in a central configuration file. Dnsmasq supports \ +static and dynamic DHCP leases and BOOTP for network booting of diskless \ +machines. \ +" +HOMEPAGE = "http://www.thekelleys.org.uk/dnsmasq" +SECTION = "net" + +# GPLv3 was added in version 2.41 as license option +LICENSE = "GPLv2 | GPLv3" +LIC_FILES_CHKSUM = "\ + file://COPYING;md5=0636e73ff0215e8d672dc4c32c317bb3 \ + file://COPYING-v3;md5=d32239bcb673463ab874e80d47fae504 \ +" + +SRC_URI = " \ + http://www.thekelleys.org.uk/${BPN}/${BP}.tar.gz \ + file://init \ + file://dnsmasq-resolvconf.service \ + file://lua.patch \ + \ + file://stx/dnsmasq-2.76-dns-sleep-resume.patch \ + file://stx/dnsmasq-2.76-fix-dhcp-option-arrangements.patch \ + file://stx/dnsmasq-2.76-pftables.patch \ + file://stx/dnsmasq-2.76-fix-crash-dns-resume.patch \ + file://stx/dnsmasq-2.76-warning-fixes.patch \ + file://stx/dnsmasq-2.76-label-warning.patch \ + file://stx/dnsmasq-2.76-label-man.patch \ + file://stx/dnsmasq-2.76-coverity.patch \ + file://stx/dnsmasq-2.76-dhcp-script-log.patch \ + file://stx/dnsmasq-2.76-file_offset32.patch \ + file://stx/dnsmasq-2.76-CVE-2017-14491.patch \ + file://stx/dnsmasq-2.76-CVE-2017-14492.patch \ + file://stx/dnsmasq-2.76-CVE-2017-14493.patch \ + file://stx/dnsmasq-2.76-CVE-2017-14494.patch \ + file://stx/dnsmasq-2.76-CVE-2017-14496.patch \ + file://stx/dnsmasq-2.76-CVE-2017-14495.patch \ + file://stx/dnsmasq-2.76-gita3303e196.patch \ + file://stx/dnsmasq-2.76-underflow.patch \ + file://stx/dnsmasq-2.76-misc-cleanups.patch \ + file://stx/dnsmasq-2.76-CVE-2017-14491-2.patch \ + file://stx/dnsmasq-2.76-inotify.patch \ + file://stx/dnsmasq-update-ipv6-leases-from-config.patch \ + file://stx/close-tftp-sockets-immediately.patch \ + file://stx/dnsmasq.service \ +" +SRC_URI[md5sum] = "6610f8233ca89b15a1bb47c788ffb84f" +SRC_URI[sha256sum] = "777c4762d2fee3738a0380401f2d087b47faa41db2317c60660d69ad10a76c32" + +inherit pkgconfig update-rc.d systemd + +INITSCRIPT_NAME = "dnsmasq" +INITSCRIPT_PARAMS = "defaults" + +PACKAGECONFIG ?= "dbus idn" +PACKAGECONFIG[dbus] = ",,dbus" +PACKAGECONFIG[idn] = ",,libidn" +PACKAGECONFIG[conntrack] = ",,libnetfilter-conntrack" +PACKAGECONFIG[lua] = ",,lua" +PACKAGECONFIG[resolvconf] = ",,,resolvconf" + +EXTRA_OEMAKE = "\ + 'COPTS=${@bb.utils.contains('PACKAGECONFIG', 'dbus', '-DHAVE_DBUS', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'idn', '-DHAVE_IDN', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'conntrack', '-DHAVE_CONNTRACK', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'lua', '-DHAVE_LUASCRIPT', '', d)}' \ + 'CFLAGS=${CFLAGS}' \ + 'LDFLAGS=${LDFLAGS}' \ +" + +SRC_URI += "${@bb.utils.contains('PACKAGECONFIG', 'resolvconf', 'file://dnsmasq.resolvconf file://99_dnsmasq file://dnsmasq-resolvconf-helper', '', d)}" + +do_compile_append() { + # build dhcp_release + cd ${S}/contrib/lease-tools + oe_runmake +} + +do_install () { + oe_runmake "PREFIX=${D}${prefix}" \ + "BINDIR=${D}${bindir}" \ + "MANDIR=${D}${mandir}" \ + install + + install -d ${D}${sysconfdir}/ + install -d ${D}${sysconfdir}/init.d + install -d ${D}${sysconfdir}/dnsmasq.d + + install -m 644 ${S}/dnsmasq.conf.example ${D}${sysconfdir}/dnsmasq.conf + cat << EOF >> ${D}${sysconfdir}/dnsmasq.conf + +# Include all files in /etc/dnsmasq.d except RPM backup files +conf-dir=/etc/dnsmasq.d,.rpmnew,.rpmsave,.rpmorig +EOF + + install -m 755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/dnsmasq + + install -d ${D}${systemd_system_unitdir} + + if [ "${@bb.utils.filter('PACKAGECONFIG', 'resolvconf', d)}" ]; then + install -m 0644 ${WORKDIR}/dnsmasq-resolvconf.service ${D}${systemd_system_unitdir}/dnsmasq.service + else + install -m 0644 ${WORKDIR}/stx/dnsmasq.service ${D}${systemd_system_unitdir}/dnsmasq.service + fi + + install -m 0755 ${S}/contrib/lease-tools/dhcp_release ${D}${bindir} + install -m 0755 ${S}/contrib/lease-tools/dhcp_release6 ${D}${bindir} + install -m 0755 ${S}/contrib/lease-tools/dhcp_lease_time ${D}${bindir} + + if [ "${@bb.utils.filter('PACKAGECONFIG', 'dbus', d)}" ]; then + install -d ${D}${sysconfdir}/dbus-1/system.d + install -m 644 dbus/dnsmasq.conf ${D}${sysconfdir}/dbus-1/system.d/ + fi + if [ "${@bb.utils.filter('PACKAGECONFIG', 'resolvconf', d)}" ]; then + install -d ${D}${sysconfdir}/resolvconf/update.d/ + install -m 0755 ${WORKDIR}/dnsmasq.resolvconf ${D}${sysconfdir}/resolvconf/update.d/dnsmasq + + install -d ${D}${sysconfdir}/default/volatiles + install -m 0644 ${WORKDIR}/99_dnsmasq ${D}${sysconfdir}/default/volatiles + install -m 0755 ${WORKDIR}/dnsmasq-resolvconf-helper ${D}${bindir} + fi +} + +CONFFILES_${PN} = "${sysconfdir}/dnsmasq.conf" + +RPROVIDES_${PN} += "${PN}-systemd" +RREPLACES_${PN} += "${PN}-systemd" +RCONFLICTS_${PN} += "${PN}-systemd" +SYSTEMD_SERVICE_${PN} = "dnsmasq.service" -- 2.16.6