Drop dnsmasq

This will be replaced by unbound

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
This commit is contained in:
Michael Tremer
2016-08-06 19:25:48 +01:00
parent b8f5eda86b
commit 61b4250af5
27 changed files with 1 additions and 1448 deletions

View File

@@ -30,7 +30,6 @@ nobody:x:99:
users:x:100:
snort:x:101:
logwatch:x:102:
dnsmasq:x:103:
cron:x:104:
syslogd:x:105:
klogd:x:106:

View File

@@ -14,7 +14,6 @@ nobody:x:99:99:Nobody:/home/nobody:/bin/false
postfix:x:100:100::/var/spool/postfix:/bin/false
snort:x:101:101:ftp:/var/log/snort:/bin/false
logwatch:x:102:102::/var/log/logwatch:/bin/false
dnsmasq:x:103:103::/:/bin/false
cron:x:104:104::/:/bin/false
syslogd:x:105:105:/var/empty:/bin/false
klogd:x:106:106:/var/empty:/bin/false

View File

@@ -26,7 +26,6 @@ etc/rc.d/init.d/console
etc/rc.d/init.d/dhcp
etc/rc.d/init.d/dhcrelay
#etc/rc.d/init.d/dnsdist
etc/rc.d/init.d/dnsmasq
etc/rc.d/init.d/fcron
#etc/rc.d/init.d/fetchmail
etc/rc.d/init.d/fireinfo
@@ -76,7 +75,6 @@ etc/rc.d/init.d/networking/green
etc/rc.d/init.d/networking/orange
etc/rc.d/init.d/networking/red
#etc/rc.d/init.d/networking/red.down
etc/rc.d/init.d/networking/red.down/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.down/10-ipsec
etc/rc.d/init.d/networking/red.down/10-miniupnpd
etc/rc.d/init.d/networking/red.down/10-ovpn
@@ -84,7 +82,6 @@ etc/rc.d/init.d/networking/red.down/10-static-routes
etc/rc.d/init.d/networking/red.down/20-firewall
#etc/rc.d/init.d/networking/red.up
etc/rc.d/init.d/networking/red.up/01-conntrack-cleanup
etc/rc.d/init.d/networking/red.up/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.up/10-miniupnpd
etc/rc.d/init.d/networking/red.up/10-multicast
etc/rc.d/init.d/networking/red.up/10-static-routes

View File

@@ -1,2 +0,0 @@
usr/sbin/dnsmasq
#usr/share/man/man8/dnsmasq.8

View File

@@ -27,7 +27,6 @@ etc/rc.d/init.d/console
etc/rc.d/init.d/dhcp
etc/rc.d/init.d/dhcrelay
#etc/rc.d/init.d/dnsdist
etc/rc.d/init.d/dnsmasq
etc/rc.d/init.d/fcron
#etc/rc.d/init.d/fetchmail
etc/rc.d/init.d/fireinfo
@@ -78,7 +77,6 @@ etc/rc.d/init.d/networking/green
etc/rc.d/init.d/networking/orange
etc/rc.d/init.d/networking/red
#etc/rc.d/init.d/networking/red.down
etc/rc.d/init.d/networking/red.down/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.down/10-ipsec
etc/rc.d/init.d/networking/red.down/10-miniupnpd
etc/rc.d/init.d/networking/red.down/10-ovpn
@@ -86,7 +84,6 @@ etc/rc.d/init.d/networking/red.down/10-static-routes
etc/rc.d/init.d/networking/red.down/20-firewall
#etc/rc.d/init.d/networking/red.up
etc/rc.d/init.d/networking/red.up/01-conntrack-cleanup
etc/rc.d/init.d/networking/red.up/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.up/10-miniupnpd
etc/rc.d/init.d/networking/red.up/10-multicast
etc/rc.d/init.d/networking/red.up/10-static-routes

View File

@@ -5,7 +5,6 @@ usr/local/bin/backupctrl
usr/local/bin/collectdctrl
usr/local/bin/ddnsctrl
usr/local/bin/dhcpctrl
usr/local/bin/dnsmasqctrl
usr/local/bin/extrahdctrl
usr/local/bin/fireinfoctrl
usr/local/bin/getconntracktable

View File

@@ -27,7 +27,6 @@ etc/rc.d/init.d/console
etc/rc.d/init.d/dhcp
etc/rc.d/init.d/dhcrelay
#etc/rc.d/init.d/dnsdist
etc/rc.d/init.d/dnsmasq
etc/rc.d/init.d/fcron
#etc/rc.d/init.d/fetchmail
etc/rc.d/init.d/fireinfo
@@ -78,7 +77,6 @@ etc/rc.d/init.d/networking/green
etc/rc.d/init.d/networking/orange
etc/rc.d/init.d/networking/red
#etc/rc.d/init.d/networking/red.down
etc/rc.d/init.d/networking/red.down/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.down/10-ipsec
etc/rc.d/init.d/networking/red.down/10-miniupnpd
etc/rc.d/init.d/networking/red.down/10-ovpn
@@ -86,7 +84,6 @@ etc/rc.d/init.d/networking/red.down/10-static-routes
etc/rc.d/init.d/networking/red.down/20-firewall
#etc/rc.d/init.d/networking/red.up
etc/rc.d/init.d/networking/red.up/01-conntrack-cleanup
etc/rc.d/init.d/networking/red.up/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.up/10-miniupnpd
etc/rc.d/init.d/networking/red.up/10-multicast
etc/rc.d/init.d/networking/red.up/10-static-routes

View File

@@ -1,100 +0,0 @@
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2016 Michael Tremer & Christian Schmidt #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
###############################################################################
# Definitions
###############################################################################
include Config
VER = 2.76
THISAPP = dnsmasq-$(VER)
DL_FILE = $(THISAPP).tar.xz
DL_FROM = $(URL_IPFIRE)
DIR_APP = $(DIR_SRC)/$(THISAPP)
TARGET = $(DIR_INFO)/$(THISAPP)
# We cannot use INOTIFY because our ISC reader code does not support that
COPTS = -DHAVE_ISC_READER -DNO_INOTIFY
###############################################################################
# Top-level Rules
###############################################################################
objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
$(DL_FILE)_MD5 = 00f5ee66b4e4b7f14538bf62ae3c9461
install : $(TARGET)
check : $(patsubst %,$(DIR_CHK)/%,$(objects))
download :$(patsubst %,$(DIR_DL)/%,$(objects))
md5 : $(subst %,%_MD5,$(objects))
###############################################################################
# Downloading, checking, md5sum
###############################################################################
$(patsubst %,$(DIR_CHK)/%,$(objects)) :
@$(CHECK)
$(patsubst %,$(DIR_DL)/%,$(objects)) :
@$(LOAD)
$(subst %,%_MD5,$(objects)) :
@$(MD5)
###############################################################################
# Installation Details
###############################################################################
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
@$(PREBUILD)
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE)
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/001-Calculate_length_of_TFTP_error_reply_correctly.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/002-Zero_newly_malloc_ed_memory.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/003-Check_return_of_expand_always.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/004-Fix_editing_error_on_man_page.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/005-Manpage_typo.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/006-Fix_bad_behaviour_with_some_DHCP_option_arrangements.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/007-Fix_logic_error_in_Linux_netlink_code.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/008-Fix_problem_with_--dnssec-timestamp.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/009-malloc_memset_calloc_for_efficiency.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/010-Zero_packet_buffers_before_building_output_to_reduce_risk_of_information_leakage.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/011-Dont_reset_packet_length_on_transmission_in_case_of_retransmission.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/012-Compile-time_check_on_buffer_sizes_for_leasefile_parsing_code.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease-file.patch
cd $(DIR_APP) && sed -i src/config.h \
-e 's|/\* #define HAVE_IDN \*/|#define HAVE_IDN|g' \
-e 's|/\* #define HAVE_DNSSEC \*/|#define HAVE_DNSSEC|g' \
-e 's|#define HAVE_DHCP|//#define HAVE_DHCP|g' \
-e 's|#define HAVE_DHCP6|//#define HAVE_DHCP6|g' \
-e 's|#define HAVE_TFTP|//#define HAVE_TFTP|g'
cd $(DIR_APP) && make CFLAGS="$(CFLAGS)" COPTS="$(COPTS)" \
PREFIX=/usr all install
@rm -rf $(DIR_APP)
@$(POSTBUILD)

View File

@@ -185,13 +185,11 @@ $(TARGET) :
ln -sf ../init.d/wlanclient /etc/rc.d/rc3.d/S19wlanclient
ln -sf ../init.d/wlanclient /etc/rc.d/rc6.d/K82wlanclient
ln -sf ../../dnsmasq /etc/rc.d/init.d/networking/red.up/05-RS-dnsmasq
ln -sf ../../../../../usr/local/bin/snortctrl \
/etc/rc.d/init.d/networking/red.up/23-RS-snort
ln -sf ../../../../../usr/local/bin/qosctrl \
/etc/rc.d/init.d/networking/red.up/24-RS-qos
ln -sf ../../squid /etc/rc.d/init.d/networking/red.up/27-RS-squid
ln -sf ../../dnsmasq /etc/rc.d/init.d/networking/red.down/05-RS-dnsmasq
for i in green blue orange; do \
ln -sf any /etc/rc.d/init.d/networking/$$i; \

View File

@@ -537,7 +537,6 @@ buildipfire() {
ipfiremake beep
ipfiremake dvdrtools
ipfiremake nettle
ipfiremake dnsmasq
ipfiremake unbound
ipfiremake dosfstools
ipfiremake reiserfsprogs

View File

@@ -1,145 +0,0 @@
#!/bin/sh
########################################################################
# Begin $rc_base/init.d/dnsmasq
#
# Description : dnsmasq init script
#
# Authors : Michael Tremer - mitch@ipfire.org
#
# Version : 01.00
#
# Notes :
#
########################################################################
. /etc/sysconfig/rc
. ${rc_functions}
CACHE_SIZE=2500
ENABLE_DNSSEC=1
SHOW_SRV=1
TRUST_ANCHOR=".,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
TIMESTAMP_FILE="/var/ipfire/dns/dnssec-timestamp"
# Pull custom configuration file
if [ -e "/etc/sysconfig/dnsmasq" ]; then
. /etc/sysconfig/dnsmasq
fi
function dnssec_args() {
local cmdline="--dnssec --dnssec-timestamp ${TIMESTAMP_FILE}"
if [ -n "${TRUST_ANCHOR}" ]; then
cmdline="${cmdline} --trust-anchor=${TRUST_ANCHOR}"
fi
echo "${cmdline}"
}
function dns_forward_args() {
local file="${1}"
# Do nothing if file is empty.
[ -s "${file}" ] || return
local cmdline
local enabled zone server remark
while IFS="," read -r enabled zone server remark; do
# Line must be enabled.
[ "${enabled}" = "on" ] || continue
cmdline="${cmdline} --server=/${zone}/${server}"
done < ${file}
echo "${cmdline}"
}
function dns_leases_args() {
eval $(/usr/local/bin/readhash /var/ipfire/dhcp/settings)
# If the DHCP server is enabled and DNS Update (RFC2136) is
# enabled, too, we won't overlay the internal domain with
# the dynamic/static leases.
if ([ "${ENABLE_GREEN}" = "on" ] || [ "${ENABLE_BLUE}" = "on" ]) \
&& [ "${DNS_UPDATE_ENABLED}" = "on" ]; then
return
fi
echo "-l /var/state/dhcp/dhcpd.leases"
}
case "${1}" in
start)
# kill already running copy of dnsmasq...
killproc /usr/sbin/dnsmasq 2>&1 > /dev/null
boot_mesg "Starting Domain Name Service Proxy..."
eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
ARGS="$CUSTOM_ARGS"
[ "$DOMAIN_NAME_GREEN" != "" ] && ARGS="$ARGS -s $DOMAIN_NAME_GREEN"
# DHCP configuration
ARGS="${ARGS} $(dns_leases_args)"
echo > /var/ipfire/red/resolv.conf # Clear it
if [ -e "/var/ipfire/red/dns1" ]; then
DNS1=$(cat /var/ipfire/red/dns1 2>/dev/null)
if [ ! -z ${DNS1} ]; then
echo "nameserver ${DNS1}" >> /var/ipfire/red/resolv.conf
fi
fi
if [ -e "/var/ipfire/red/dns2" ]; then
DNS2=$(cat /var/ipfire/red/dns2 2>/dev/null)
if [ ! -z ${DNS2} ]; then
echo "nameserver ${DNS2}" >> /var/ipfire/red/resolv.conf
fi
fi
[ -e "/var/ipfire/red/active" ] && ARGS="$ARGS -r /var/ipfire/red/resolv.conf"
ARGS="$ARGS --domain=`cat /var/ipfire/main/settings |grep DOMAIN |cut -d = -f 2`"
# Add custom forward dns zones.
ARGS="${ARGS} $(dns_forward_args /var/ipfire/dnsforward/config)"
# Enabled DNSSEC validation
if [ "${ENABLE_DNSSEC}" -eq 1 ]; then
ARGS="${ARGS} $(dnssec_args)"
fi
if [ -n "${CACHE_SIZE}" ]; then
ARGS="${ARGS} --cache-size=${CACHE_SIZE}"
fi
loadproc /usr/sbin/dnsmasq ${ARGS}
if [ "${SHOW_SRV}" -eq 1 ] && [ "${DNS1}" != "" -o "${DNS2}" != "" ]; then
boot_mesg "Using DNS server(s): ${DNS1} ${DNS2}"
boot_mesg_flush
fi
;;
stop)
boot_mesg "Stopping Domain Name Service Proxy..."
killproc /usr/sbin/dnsmasq
;;
restart)
${0} stop
sleep 1
${0} start
;;
status)
statusproc /usr/sbin/dnsmasq
;;
*)
echo "Usage: ${0} {start|stop|restart|status}"
exit 1
;;
esac
# End $rc_base/init.d/dnsmasq

View File

@@ -16,10 +16,6 @@
. ${rc_functions}
eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
init_networking() {
/etc/rc.d/init.d/dnsmasq start
}
DO="${1}"
shift
@@ -46,8 +42,6 @@ done
case "${DO}" in
start)
[ "${ALL}" == "1" ] && init_networking
# Starting interfaces...
# GREEN
[ "$green" == "1" ] && /etc/rc.d/init.d/networking/green start
@@ -92,9 +86,6 @@ case "${DO}" in
fi
fi
# Stopping dnsmasq if network all networks shutdown
[ "${ALL}" == "1" ] && /etc/rc.d/init.d/dnsmasq stop
exit 0
;;

View File

@@ -31,7 +31,7 @@ SUID_PROGS = squidctrl sshctrl ipfirereboot \
redctrl syslogdctrl extrahdctrl sambactrl upnpctrl \
smartctrl clamavctrl addonctrl pakfire mpfirectrl wlanapctrl \
setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes \
getconntracktable wirelessclient dnsmasqctrl torctrl ddnsctrl
getconntracktable wirelessclient torctrl ddnsctrl
SUID_UPDX = updxsetperms
OBJS = $(patsubst %,%.o,$(PROGS) $(SUID_PROGS))

View File

@@ -1,34 +0,0 @@
/* This file is part of the IPFire Firewall.
*
* This program is distributed under the terms of the GNU General Public
* Licence. See the file COPYING for details.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include "setuid.h"
int main(int argc, char *argv[]) {
if (!(initsetuid()))
exit(1);
if (argc < 2) {
fprintf(stderr, "\nNo argument given.\n\ndnsmasqctrl (restart)\n\n");
exit(1);
}
if (strcmp(argv[1], "restart") == 0) {
safe_system("/etc/rc.d/init.d/dnsmasq restart");
} else {
fprintf(stderr, "\nBad argument given.\n\ndnsmasqctrl (restart)\n\n");
exit(1);
}
return 0;
}

View File

@@ -1,363 +0,0 @@
--- a/src/cache.c Wed Dec 16 19:24:12 2015
+++ b/src/cache.c Wed Dec 16 19:37:37 2015
@@ -17,7 +17,7 @@
#include "dnsmasq.h"
static struct crec *cache_head = NULL, *cache_tail = NULL, **hash_table = NULL;
-#ifdef HAVE_DHCP
+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER)
static struct crec *dhcp_spare = NULL;
#endif
static struct crec *new_chain = NULL;
@@ -217,6 +217,9 @@
crecp->flags &= ~F_BIGNAME;
}
+ if (crecp->flags & F_DHCP)
+ free(crecp->name.namep);
+
#ifdef HAVE_DNSSEC
cache_blockdata_free(crecp);
#endif
@@ -1138,7 +1141,7 @@
}
-#ifdef HAVE_DHCP
+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER)
struct in_addr a_record_from_hosts(char *name, time_t now)
{
struct crec *crecp = NULL;
@@ -1281,7 +1284,11 @@
else
crec->ttd = ttd;
crec->addr.addr = *host_address;
+#ifdef HAVE_ISC_READER
+ crec->name.namep = strdup(host_name);
+#else
crec->name.namep = host_name;
+#endif
crec->uid = next_uid();
cache_hash(crec);
--- a/src/dnsmasq.c Thu Jul 30 20:59:06 2015
+++ b/src/dnsmasq.c Wed Dec 16 19:38:32 2015
@@ -1017,6 +1017,11 @@
poll_resolv(0, daemon->last_resolv != 0, now);
daemon->last_resolv = now;
+
+#ifdef HAVE_ISC_READER
+ if (daemon->lease_file && !daemon->dhcp)
+ load_dhcp(now);
+#endif
}
#endif
--- a/src/dnsmasq.h Wed Dec 16 19:24:12 2015
+++ b/src/dnsmasq.h Wed Dec 16 19:40:11 2015
@@ -1516,6 +1516,11 @@
void poll_listen(int fd, short event);
int do_poll(int timeout);
+/* isc.c */
+#ifdef HAVE_ISC_READER
+void load_dhcp(time_t now);
+#endif
+
/* rrfilter.c */
size_t rrfilter(struct dns_header *header, size_t plen, int mode);
u16 *rrfilter_desc(int type);
int expand_workspace(unsigned char ***wkspc, int *szp, int new);
-
--- /dev/null Wed Dec 16 19:48:08 2015
+++ b/src/isc.c Wed Dec 16 19:41:35 2015
@@ -0,0 +1,266 @@
+/* dnsmasq is Copyright (c) 2014 John Volpe, Simon Kelley and
+ Michael Tremer
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 dated June, 1991, or
+ (at your option) version 3 dated 29 June, 2007.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ Code in this file is based on contributions by John Volpe and
+ Simon Kelley. Updated for recent versions of dnsmasq by
+ Michael Tremer.
+*/
+
+
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "dnsmasq.h"
+
+#ifdef HAVE_ISC_READER
+#define MAXTOK 50
+
+struct isc_dhcp_lease {
+ char* name;
+ char* fqdn;
+ time_t expires;
+ struct in_addr addr;
+ struct isc_dhcp_lease* next;
+};
+
+static struct isc_dhcp_lease* dhcp_lease_new(const char* hostname) {
+ struct isc_dhcp_lease* lease = whine_malloc(sizeof(*lease));
+ if (!lease)
+ return NULL;
+
+ lease->name = strdup(hostname);
+ if (daemon->domain_suffix) {
+ int r = asprintf(&lease->fqdn, "%s.%s", hostname, daemon->domain_suffix);
+
+ // Handle OOM
+ if (r < 0) {
+ free(lease);
+ return NULL;
+ }
+ }
+ lease->expires = 0;
+ lease->next = NULL;
+
+ return lease;
+}
+
+static void dhcp_lease_free(struct isc_dhcp_lease* lease) {
+ if (!lease)
+ return;
+
+ if (lease->name)
+ free(lease->name);
+ if (lease->fqdn)
+ free(lease->fqdn);
+ free(lease);
+}
+
+static int next_token(char* token, int buffsize, FILE* fp) {
+ int c, count = 0;
+ char* cp = token;
+
+ while ((c = getc(fp)) != EOF) {
+ if (c == '#') {
+ do {
+ c = getc(fp);
+ } while (c != '\n' && c != EOF);
+ }
+
+ if (c == ' ' || c == '\t' || c == '\n' || c == ';') {
+ if (count)
+ break;
+ } else if ((c != '"') && (count < buffsize - 1)) {
+ *cp++ = c;
+ count++;
+ }
+ }
+
+ *cp = 0;
+ return count ? 1 : 0;
+}
+
+static long get_utc_offset() {
+ time_t t = time(NULL);
+ struct tm* time_struct = localtime(&t);
+
+ return time_struct->tm_gmtoff;
+}
+
+static time_t parse_lease_time(const char* token_date, const char* token_time) {
+ time_t time = (time_t)(-1);
+ struct tm lease_time;
+
+ if (sscanf(token_date, "%d/%d/%d", &lease_time.tm_year, &lease_time.tm_mon, &lease_time.tm_mday) == 3) {
+ lease_time.tm_year -= 1900;
+ lease_time.tm_mon -= 1;
+
+ if (sscanf(token_time, "%d:%d:%d", &lease_time.tm_hour, &lease_time.tm_min, &lease_time.tm_sec) == 3) {
+ time = mktime(&lease_time) + get_utc_offset();
+ }
+ }
+
+ return time;
+}
+
+static struct isc_dhcp_lease* find_lease(const char* hostname, struct isc_dhcp_lease* leases) {
+ struct isc_dhcp_lease* lease = leases;
+
+ while (lease) {
+ if (strcmp(hostname, lease->name) == 0) {
+ return lease;
+ }
+ lease = lease->next;
+ }
+
+ return NULL;
+}
+
+static off_t lease_file_size = (off_t)0;
+static ino_t lease_file_inode = (ino_t)0;
+
+void load_dhcp(time_t now) {
+ struct isc_dhcp_lease* leases = NULL;
+
+ struct stat statbuf;
+ if (stat(daemon->lease_file, &statbuf) == -1) {
+ return;
+ }
+
+ /* Do nothing if the lease file has not changed. */
+ if ((statbuf.st_size <= lease_file_size) && (statbuf.st_ino == lease_file_inode))
+ return;
+
+ lease_file_size = statbuf.st_size;
+ lease_file_inode = statbuf.st_ino;
+
+ FILE* fp = fopen(daemon->lease_file, "r");
+ if (!fp) {
+ my_syslog(LOG_ERR, _("failed to load %s:%s"), daemon->lease_file, strerror(errno));
+ return;
+ }
+
+ my_syslog(LOG_INFO, _("reading %s"), daemon->lease_file);
+
+ char* hostname = daemon->namebuff;
+ struct in_addr host_address;
+ time_t time_starts = -1;
+ time_t time_ends = -1;
+ int nomem;
+
+ char token[MAXTOK];
+ while ((next_token(token, MAXTOK, fp))) {
+ if (strcmp(token, "lease") == 0) {
+ hostname[0] = '\0';
+
+ if (next_token(token, MAXTOK, fp) && ((host_address.s_addr = inet_addr(token)) != (in_addr_t)-1)) {
+ if (next_token(token, MAXTOK, fp) && *token == '{') {
+ while (next_token(token, MAXTOK, fp) && *token != '}') {
+ if ((strcmp(token, "client-hostname") == 0) || (strcmp(token, "hostname") == 0)) {
+ if (next_token(hostname, MAXDNAME, fp)) {
+ if (!canonicalise(hostname, &nomem)) {
+ *hostname = 0;
+ my_syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file);
+ }
+ }
+ } else if ((strcmp(token, "starts") == 0) || (strcmp(token, "ends") == 0)) {
+ char token_date[MAXTOK];
+ char token_time[MAXTOK];
+
+ int is_starts = strcmp(token, "starts") == 0;
+
+ // Throw away the weekday and parse the date.
+ if (next_token(token, MAXTOK, fp) && next_token(token_date, MAXTOK, fp) && next_token(token_time, MAXTOK, fp)) {
+ time_t time = parse_lease_time(token_date, token_time);
+
+ if (is_starts)
+ time_starts = time;
+ else
+ time_ends = time;
+ }
+ }
+ }
+
+ if (!*hostname)
+ continue;
+
+ if ((time_starts == -1) || (time_ends == -1))
+ continue;
+
+ if (difftime(now, time_ends) > 0)
+ continue;
+
+ char* dot = strchr(hostname, '.');
+ if (dot) {
+ if (!daemon->domain_suffix || hostname_isequal(dot + 1, daemon->domain_suffix)) {
+ my_syslog(LOG_WARNING,
+ _("Ignoring DHCP lease for %s because it has an illegal domain part"),
+ hostname);
+ continue;
+ }
+ *dot = 0;
+ }
+
+ // Search for an existing lease in the list
+ // with the given host name and update the data
+ // if needed.
+ struct isc_dhcp_lease* lease = find_lease(hostname, leases);
+
+ // If no lease already exists, we create a new one
+ // and append it to the list.
+ if (!lease) {
+ lease = dhcp_lease_new(hostname);
+ assert(lease);
+
+ lease->next = leases;
+ leases = lease;
+ }
+
+ // Only update more recent leases.
+ if (lease->expires > time_ends)
+ continue;
+
+ lease->addr = host_address;
+ lease->expires = time_ends;
+ }
+ }
+ }
+ }
+
+ fclose(fp);
+
+ // Drop all entries.
+ cache_unhash_dhcp();
+
+ while (leases) {
+ struct isc_dhcp_lease *lease = leases;
+ leases = lease->next;
+
+ if (lease->fqdn) {
+ cache_add_dhcp_entry(lease->fqdn, AF_INET, (struct all_addr*)&lease->addr.s_addr, lease->expires);
+ }
+
+ if (lease->name) {
+ cache_add_dhcp_entry(lease->name, AF_INET, (struct all_addr*)&lease->addr.s_addr, lease->expires);
+ }
+
+ // Cleanup
+ dhcp_lease_free(lease);
+ }
+}
+
+#endif
--- a/src/option.c Wed Dec 16 19:24:12 2015
+++ b/src/option.c Wed Dec 16 19:42:48 2015
@@ -1771,7 +1771,7 @@
ret_err(_("bad MX target"));
break;
-#ifdef HAVE_DHCP
+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER)
case 'l': /* --dhcp-leasefile */
daemon->lease_file = opt_string_alloc(arg);
break;
--- a/Makefile Wed Dec 16 19:24:12 2015
+++ b/Makefile Wed Dec 16 19:28:45 2015
@@ -74,7 +74,7 @@
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \
domain.o dnssec.o blockdata.o tables.o loop.o inotify.o \
- poll.o rrfilter.o edns0.o arp.o
+ poll.o rrfilter.o edns0.o arp.o isc.o
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
dns-protocol.h radv-protocol.h ip6addr.h

View File

@@ -1,65 +0,0 @@
From 294d36df4749e01199ab220d44c170e7db2b0c05 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 6 Jul 2016 21:30:25 +0100
Subject: [PATCH] Calculate length of TFTP error reply correctly.
---
CHANGELOG | 14 ++++++++++++++
src/tftp.c | 7 +++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 04ff3f0..0559a6f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,17 @@
+version 2.77
+ Calculate the length of TFTP error reply packet
+ correctly. This fixes a problem when the error
+ message in a TFTP packet exceeds the arbitrary
+ limit of 500 characters. The message was correctly
+ truncated, but not the packet length, so
+ extra data was appended. This is a possible
+ security risk, since the extra data comes from
+ a buffer which is also used for DNS, so that
+ previous DNS queries or replies may be leaked.
+ Thanks to Mozilla for funding the security audit
+ which spotted this bug.
+
+
version 2.76
Include 0.0.0.0/8 in DNS rebind checks. This range
translates to hosts on the local network, or, at
diff --git a/src/tftp.c b/src/tftp.c
index 5e4a32a..3e1b5c5 100644
--- a/src/tftp.c
+++ b/src/tftp.c
@@ -652,20 +652,23 @@ static void sanitise(char *buf)
}
+#define MAXMESSAGE 500 /* limit to make packet < 512 bytes and definitely smaller than buffer */
static ssize_t tftp_err(int err, char *packet, char *message, char *file)
{
struct errmess {
unsigned short op, err;
char message[];
} *mess = (struct errmess *)packet;
- ssize_t ret = 4;
+ ssize_t len, ret = 4;
char *errstr = strerror(errno);
sanitise(file);
mess->op = htons(OP_ERR);
mess->err = htons(err);
- ret += (snprintf(mess->message, 500, message, file, errstr) + 1);
+ len = snprintf(mess->message, MAXMESSAGE, message, file, errstr);
+ ret += (len < MAXMESSAGE) ? len + 1 : MAXMESSAGE; /* include terminating zero */
+
my_syslog(MS_TFTP | LOG_ERR, "%s", mess->message);
return ret;
--
1.7.10.4

View File

@@ -1,36 +0,0 @@
From d55f81f5fd53b1dfc2c4b3249b542f2d9679e236 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 6 Jul 2016 21:33:56 +0100
Subject: [PATCH] Zero newly malloc'ed memory.
---
src/util.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/util.c b/src/util.c
index 93b24f5..82443c9 100644
--- a/src/util.c
+++ b/src/util.c
@@ -248,6 +248,8 @@ void *safe_malloc(size_t size)
if (!ret)
die(_("could not get memory"), NULL, EC_NOMEM);
+ else
+ memset(ret, 0, size);
return ret;
}
@@ -266,7 +268,9 @@ void *whine_malloc(size_t size)
if (!ret)
my_syslog(LOG_ERR, _("failed to allocate %d bytes"), (int) size);
-
+ else
+ memset(ret, 0, size);
+
return ret;
}
--
1.7.10.4

View File

@@ -1,44 +0,0 @@
From ce7845bf5429bd2962c9b2e7d75e2659f3b5c1a8 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 6 Jul 2016 21:42:27 +0100
Subject: [PATCH] Check return of expand() always.
---
src/radv.c | 4 +++-
src/slaac.c | 5 ++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/radv.c b/src/radv.c
index 749b666..faa0f6d 100644
--- a/src/radv.c
+++ b/src/radv.c
@@ -262,7 +262,9 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
parm.prio = calc_prio(ra_param);
save_counter(0);
- ra = expand(sizeof(struct ra_packet));
+
+ if (!(ra = expand(sizeof(struct ra_packet))))
+ return;
ra->type = ND_ROUTER_ADVERT;
ra->code = 0;
diff --git a/src/slaac.c b/src/slaac.c
index 8034805..07b8ba4 100644
--- a/src/slaac.c
+++ b/src/slaac.c
@@ -147,7 +147,10 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
struct sockaddr_in6 addr;
save_counter(0);
- ping = expand(sizeof(struct ping_packet));
+
+ if (!(ping = expand(sizeof(struct ping_packet))))
+ continue;
+
ping->type = ICMP6_ECHO_REQUEST;
ping->code = 0;
ping->identifier = ping_id;
--
1.7.10.4

View File

@@ -1,40 +0,0 @@
From 5874f3e9222397d82aabd9884d9bf5ce7e4109b0 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Sun, 10 Jul 2016 22:12:08 +0100
Subject: [PATCH] Fix editing error on man page.
Thanks to Eric Westbrook for spotting this.
---
man/dnsmasq.8 | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index 0521534..bd8c0b3 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -1037,6 +1037,10 @@ is given, then read all the files contained in that directory. The advantage of
using this option is the same as for --dhcp-hostsfile: the
dhcp-optsfile will be re-read when dnsmasq receives SIGHUP. Note that
it is possible to encode the information in a
+.B --dhcp-boot
+flag as DHCP options, using the options names bootfile-name,
+server-ip-address and tftp-server. This allows these to be included
+in a dhcp-optsfile.
.TP
.B --dhcp-hostsdir=<path>
This is equivalent to dhcp-hostsfile, except for the following. The path MUST be a
@@ -1048,11 +1052,6 @@ is restarted; ie host records are only added dynamically.
.TP
.B --dhcp-optsdir=<path>
This is equivalent to dhcp-optsfile, with the differences noted for --dhcp-hostsdir.
-.TP
-.B --dhcp-boot
-flag as DHCP options, using the options names bootfile-name,
-server-ip-address and tftp-server. This allows these to be included
-in a dhcp-optsfile.
.TP
.B \-Z, --read-ethers
Read /etc/ethers for information about hosts for the DHCP server. The
--
1.7.10.4

View File

@@ -1,25 +0,0 @@
From 907efeb2dc712603271093bce8a93c7c3e6fe64d Mon Sep 17 00:00:00 2001
From: Kristjan Onu <jeixav@gmail.com>
Date: Sun, 10 Jul 2016 22:37:57 +0100
Subject: [PATCH] Manpage typo.
---
man/dnsmasq.8 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index bd8c0b3..ac8d921 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -242,7 +242,7 @@ addresses associated with the interface.
.B --local-service
Accept DNS queries only from hosts whose address is on a local subnet,
ie a subnet for which an interface exists on the server. This option
-only has effect is there are no --interface --except-interface,
+only has effect if there are no --interface --except-interface,
--listen-address or --auth-server options. It is intended to be set as
a default on installation, to allow unconfigured installations to be
useful but also safe from being used for DNS amplification attacks.
--
1.7.10.4

View File

@@ -1,49 +0,0 @@
From 591ed1e90503817938ccf5f127e677a8dd48b6d8 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
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;
--
1.7.10.4

View File

@@ -1,55 +0,0 @@
From 1d07667ac77c55b9de56b1b2c385167e0e0ec27a Mon Sep 17 00:00:00 2001
From: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Date: Mon, 11 Jul 2016 18:36:05 +0100
Subject: [PATCH] Fix logic error in Linux netlink code.
This could cause dnsmasq to enter a tight loop on systems
with a very large number of network interfaces.
---
CHANGELOG | 6 ++++++
src/netlink.c | 8 +++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0559a6f..59c9c49 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,12 @@ version 2.77
Thanks to Mozilla for funding the security audit
which spotted this bug.
+ Fix logic error in Linux netlink code. This could
+ cause dnsmasq to enter a tight loop on systems
+ with a very large number of network interfaces.
+ Thanks to Ivan Kokshaysky for the diagnosis and
+ patch.
+
version 2.76
Include 0.0.0.0/8 in DNS rebind checks. This range
diff --git a/src/netlink.c b/src/netlink.c
index 049247b..8cd51af 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -188,11 +188,17 @@ int iface_enumerate(int family, void *parm, int (*callback)())
}
for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
- if (h->nlmsg_seq != seq || h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)
+ if (h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)
{
/* May be multicast arriving async */
nl_async(h);
}
+ else if (h->nlmsg_seq != seq)
+ {
+ /* May be part of incomplete response to previous request after
+ ENOBUFS. Drop it. */
+ continue;
+ }
else if (h->nlmsg_type == NLMSG_DONE)
return callback_ok;
else if (h->nlmsg_type == RTM_NEWADDR && family != AF_UNSPEC && family != AF_LOCAL)
--
1.7.10.4

View File

@@ -1,93 +0,0 @@
From 06093a9a845bb597005d892d5d1bc7859933ada4 Mon Sep 17 00:00:00 2001
From: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
Date: Mon, 11 Jul 2016 21:03:27 +0100
Subject: [PATCH] Fix problem with --dnssec-timestamp whereby receipt of
SIGHUP would erroneously engage timestamp checking.
---
CHANGELOG | 4 ++++
src/dnsmasq.c | 7 ++++---
src/dnsmasq.h | 1 +
src/dnssec.c | 5 +++--
4 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 59c9c49..9f1e404 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,10 @@ version 2.77
Thanks to Ivan Kokshaysky for the diagnosis and
patch.
+ Fix problem with --dnssec-timestamp whereby receipt
+ of SIGHUP would erroneously engage timestamp checking.
+ Thanks to Kevin Darbyshire-Bryant for this work.
+
version 2.76
Include 0.0.0.0/8 in DNS rebind checks. This range
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 045ec53..a47273f 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -750,7 +750,8 @@ int main (int argc, char **argv)
my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
- if (option_bool(OPT_DNSSEC_TIME))
+ daemon->dnssec_no_time_check = option_bool(OPT_DNSSEC_TIME);
+ if (option_bool(OPT_DNSSEC_TIME) && !daemon->back_to_the_future)
my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until first cache reload"));
if (rc == 1)
@@ -1226,10 +1227,10 @@ static void async_event(int pipe, time_t now)
{
case EVENT_RELOAD:
#ifdef HAVE_DNSSEC
- if (option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME))
+ if (daemon->dnssec_no_time_check && option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME))
{
my_syslog(LOG_INFO, _("now checking DNSSEC signature timestamps"));
- reset_option_bool(OPT_DNSSEC_TIME);
+ daemon->dnssec_no_time_check = 0;
}
#endif
/* fall through */
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 1896a64..be27ae0 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -992,6 +992,7 @@ extern struct daemon {
#endif
#ifdef HAVE_DNSSEC
struct ds_config *ds;
+ int dnssec_no_time_check;
int back_to_the_future;
char *timestamp_file;
#endif
diff --git a/src/dnssec.c b/src/dnssec.c
index 3c77c7d..64358fa 100644
--- a/src/dnssec.c
+++ b/src/dnssec.c
@@ -522,15 +522,16 @@ static int check_date_range(u32 date_start, u32 date_end)
if (utime(daemon->timestamp_file, NULL) != 0)
my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
+ my_syslog(LOG_INFO, _("system time considered valid, now checking DNSSEC signature timestamps."));
daemon->back_to_the_future = 1;
- set_option_bool(OPT_DNSSEC_TIME);
+ daemon->dnssec_no_time_check = 0;
queue_event(EVENT_RELOAD); /* purge cache */
}
if (daemon->back_to_the_future == 0)
return 1;
}
- else if (option_bool(OPT_DNSSEC_TIME))
+ else if (daemon->dnssec_no_time_check)
return 1;
/* We must explicitly check against wanted values, because of SERIAL_UNDEF */
--
1.7.10.4

View File

@@ -1,46 +0,0 @@
From d6dce53e08b3a06be16d43e1bf566c6c1988e4a9 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 11 Jul 2016 21:34:31 +0100
Subject: [PATCH] malloc(); memset() -> calloc() for efficiency.
---
src/util.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/src/util.c b/src/util.c
index 82443c9..211690e 100644
--- a/src/util.c
+++ b/src/util.c
@@ -244,13 +244,11 @@ unsigned char *do_rfc1035_name(unsigned char *p, char *sval)
/* for use during startup */
void *safe_malloc(size_t size)
{
- void *ret = malloc(size);
+ void *ret = calloc(1, size);
if (!ret)
die(_("could not get memory"), NULL, EC_NOMEM);
- else
- memset(ret, 0, size);
-
+
return ret;
}
@@ -264,12 +262,10 @@ void safe_pipe(int *fd, int read_noblock)
void *whine_malloc(size_t size)
{
- void *ret = malloc(size);
+ void *ret = calloc(1, size);
if (!ret)
my_syslog(LOG_ERR, _("failed to allocate %d bytes"), (int) size);
- else
- memset(ret, 0, size);
return ret;
}
--
1.7.10.4

View File

@@ -1,169 +0,0 @@
From fa78573778cb23337f67f5d0c9de723169919047 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri, 22 Jul 2016 20:56:01 +0100
Subject: [PATCH] Zero packet buffers before building output, to reduce risk
of information leakage.
---
src/auth.c | 5 +++++
src/dnsmasq.h | 1 +
src/outpacket.c | 10 ++++++++++
src/radv.c | 2 +-
src/rfc1035.c | 5 +++++
src/rfc3315.c | 6 +++---
src/slaac.c | 2 +-
src/tftp.c | 5 ++++-
8 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/src/auth.c b/src/auth.c
index 198572d..3c5c37f 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -101,6 +101,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
struct all_addr addr;
struct cname *a;
+ /* Clear buffer beyond request to avoid risk of
+ information disclosure. */
+ memset(((char *)header) + qlen, 0,
+ (limit - ((char *)header)) - qlen);
+
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
return 0;
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index be27ae0..2bda5d0 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1471,6 +1471,7 @@ void log_relay(int family, struct dhcp_relay *relay);
/* outpacket.c */
#ifdef HAVE_DHCP6
void end_opt6(int container);
+void reset_counter(void);
int save_counter(int newval);
void *expand(size_t headroom);
int new_opt6(int opt);
diff --git a/src/outpacket.c b/src/outpacket.c
index a414efa..2caacd9 100644
--- a/src/outpacket.c
+++ b/src/outpacket.c
@@ -29,9 +29,19 @@ void end_opt6(int container)
PUTSHORT(len, p);
}
+void reset_counter(void)
+{
+ /* Clear out buffer when starting from begining */
+ if (daemon->outpacket.iov_base)
+ memset(daemon->outpacket.iov_base, 0, daemon->outpacket.iov_len);
+
+ save_counter(0);
+}
+
int save_counter(int newval)
{
int ret = outpacket_counter;
+
if (newval != -1)
outpacket_counter = newval;
diff --git a/src/radv.c b/src/radv.c
index faa0f6d..39c9217 100644
--- a/src/radv.c
+++ b/src/radv.c
@@ -261,7 +261,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
parm.adv_interval = calc_interval(ra_param);
parm.prio = calc_prio(ra_param);
- save_counter(0);
+ reset_counter();
if (!(ra = expand(sizeof(struct ra_packet))))
return;
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 24d08c1..9e730a9 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1209,6 +1209,11 @@ 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;
+
+ /* Clear buffer beyond request to avoid risk of
+ information disclosure. */
+ memset(((char *)header) + qlen, 0,
+ (limit - ((char *)header)) - qlen);
if (ntohs(header->ancount) != 0 ||
ntohs(header->nscount) != 0 ||
diff --git a/src/rfc3315.c b/src/rfc3315.c
index 3f4d69c..e1271a1 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -89,7 +89,7 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
vendor->netid.next = &vendor->netid;
- save_counter(0);
+ reset_counter();
state.context = context;
state.interface = interface;
state.iface_name = iface_name;
@@ -2084,7 +2084,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz,
if (hopcount > 32)
return;
- save_counter(0);
+ reset_counter();
if ((header = put_opt6(NULL, 34)))
{
@@ -2161,7 +2161,7 @@ unsigned short relay_reply6(struct sockaddr_in6 *peer, ssize_t sz, char *arrival
(!relay->interface || wildcard_match(relay->interface, arrival_interface)))
break;
- save_counter(0);
+ reset_counter();
if (relay)
{
diff --git a/src/slaac.c b/src/slaac.c
index 07b8ba4..bd6c9b4 100644
--- a/src/slaac.c
+++ b/src/slaac.c
@@ -146,7 +146,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
struct ping_packet *ping;
struct sockaddr_in6 addr;
- save_counter(0);
+ reset_counter();
if (!(ping = expand(sizeof(struct ping_packet))))
continue;
diff --git a/src/tftp.c b/src/tftp.c
index 3e1b5c5..618c406 100644
--- a/src/tftp.c
+++ b/src/tftp.c
@@ -662,8 +662,9 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file)
ssize_t len, ret = 4;
char *errstr = strerror(errno);
+ memset(packet, 0, daemon->packet_buff_sz);
sanitise(file);
-
+
mess->op = htons(OP_ERR);
mess->err = htons(err);
len = snprintf(mess->message, MAXMESSAGE, message, file, errstr);
@@ -684,6 +685,8 @@ static ssize_t tftp_err_oops(char *packet, char *file)
/* return -1 for error, zero for done. */
static ssize_t get_block(char *packet, struct tftp_transfer *transfer)
{
+ memset(packet, 0, daemon->packet_buff_sz);
+
if (transfer->block == 0)
{
/* send OACK */
--
1.7.10.4

View File

@@ -1,54 +0,0 @@
From 6b1c464d6de3d7d2afc9b53afe78cda6d6e3316f Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri, 22 Jul 2016 20:59:16 +0100
Subject: [PATCH] Don't reset packet length on transmission, in case of
retransmission.
---
src/radv.c | 2 +-
src/rfc3315.c | 2 +-
src/slaac.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/radv.c b/src/radv.c
index 39c9217..ffc37f2 100644
--- a/src/radv.c
+++ b/src/radv.c
@@ -528,7 +528,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
}
while (retry_send(sendto(daemon->icmp6fd, daemon->outpacket.iov_base,
- save_counter(0), 0, (struct sockaddr *)&addr,
+ save_counter(-1), 0, (struct sockaddr *)&addr,
sizeof(addr))));
}
diff --git a/src/rfc3315.c b/src/rfc3315.c
index e1271a1..c7bf46f 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -2127,7 +2127,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz,
my_syslog(MS_DHCP | LOG_ERR, _("Cannot multicast to DHCPv6 server without correct interface"));
}
- send_from(daemon->dhcp6fd, 0, daemon->outpacket.iov_base, save_counter(0), &to, &from, 0);
+ send_from(daemon->dhcp6fd, 0, daemon->outpacket.iov_base, save_counter(-1), &to, &from, 0);
if (option_bool(OPT_LOG_OPTS))
{
diff --git a/src/slaac.c b/src/slaac.c
index bd6c9b4..7ecf127 100644
--- a/src/slaac.c
+++ b/src/slaac.c
@@ -164,7 +164,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
addr.sin6_port = htons(IPPROTO_ICMPV6);
addr.sin6_addr = slaac->addr;
- if (sendto(daemon->icmp6fd, daemon->outpacket.iov_base, save_counter(0), 0,
+ if (sendto(daemon->icmp6fd, daemon->outpacket.iov_base, save_counter(-1), 0,
(struct sockaddr *)&addr, sizeof(addr)) == -1 &&
errno == EHOSTUNREACH)
slaac->ping_time = 0; /* Give up */
--
1.7.10.4

View File

@@ -1,103 +0,0 @@
From bf4e62c19e619f7edf8d03d58d33a5752f190bfd Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri, 22 Jul 2016 21:37:59 +0100
Subject: [PATCH] Compile-time check on buffer sizes for leasefile parsing
code.
---
src/dhcp-common.c | 16 ++++++++--------
src/dhcp-protocol.h | 4 ++++
src/lease.c | 9 ++++++++-
src/rfc3315.c | 2 +-
4 files changed, 21 insertions(+), 10 deletions(-)
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/lease.c b/src/lease.c
index 20cac90..ca62cc5 100644
--- a/src/lease.c
+++ b/src/lease.c
@@ -65,7 +65,14 @@ void lease_init(time_t now)
}
/* client-id max length is 255 which is 255*2 digits + 254 colons
- borrow DNS packet buffer which is always larger than 1000 bytes */
+ 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 leasfile parsing.
+#endif
+
if (leasestream)
while (fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2) == 2)
{
diff --git a/src/rfc3315.c b/src/rfc3315.c
index c7bf46f..568b0c8 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
--
1.7.10.4