mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
security audit changes.
git-svn-id: file:///svn/unbound/trunk@657 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
7ccfb10392
commit
41e847df18
15 changed files with 333 additions and 39 deletions
13
Makefile.in
13
Makefile.in
|
|
@ -58,24 +58,25 @@ COMMON_SRC=$(wildcard services/*.c services/cache/*.c util/*.c \
|
||||||
COMMON_OBJ=$(addprefix $(BUILD),$(COMMON_SRC:.c=.o))
|
COMMON_OBJ=$(addprefix $(BUILD),$(COMMON_SRC:.c=.o))
|
||||||
COMPAT_OBJ=$(addprefix $(BUILD)compat/,$(LIBOBJS))
|
COMPAT_OBJ=$(addprefix $(BUILD)compat/,$(LIBOBJS))
|
||||||
UNITTEST_SRC=$(wildcard testcode/unit*.c) testcode/readhex.c \
|
UNITTEST_SRC=$(wildcard testcode/unit*.c) testcode/readhex.c \
|
||||||
testcode/ldns-testpkts.c $(COMMON_SRC)
|
testcode/ldns-testpkts.c checkconf/worker_cb.c $(COMMON_SRC)
|
||||||
UNITTEST_OBJ=$(addprefix $(BUILD),$(UNITTEST_SRC:.c=.o)) $(COMPAT_OBJ)
|
UNITTEST_OBJ=$(addprefix $(BUILD),$(UNITTEST_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
DAEMON_SRC=$(wildcard daemon/*.c) $(COMMON_SRC)
|
DAEMON_SRC=$(wildcard daemon/*.c) $(COMMON_SRC)
|
||||||
DAEMON_OBJ=$(addprefix $(BUILD),$(DAEMON_SRC:.c=.o)) $(COMPAT_OBJ)
|
DAEMON_OBJ=$(addprefix $(BUILD),$(DAEMON_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
CHECKCONF_SRC=checkconf/unbound-checkconf.c $(COMMON_SRC)
|
CHECKCONF_SRC=checkconf/unbound-checkconf.c checkconf/worker_cb.c $(COMMON_SRC)
|
||||||
CHECKCONF_OBJ=$(addprefix $(BUILD),$(CHECKCONF_SRC:.c=.o)) $(COMPAT_OBJ)
|
CHECKCONF_OBJ=$(addprefix $(BUILD),$(CHECKCONF_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
TESTBOUND_SRC=testcode/testbound.c testcode/ldns-testpkts.c \
|
TESTBOUND_SRC=testcode/testbound.c testcode/ldns-testpkts.c \
|
||||||
daemon/worker.c daemon/daemon.c daemon/stats.c testcode/replay.c \
|
daemon/worker.c daemon/daemon.c daemon/stats.c testcode/replay.c \
|
||||||
testcode/fake_event.c $(filter-out util/netevent.c \
|
testcode/fake_event.c $(filter-out util/netevent.c \
|
||||||
services/listen_dnsport.c services/outside_network.c, $(COMMON_SRC))
|
services/listen_dnsport.c services/outside_network.c, $(COMMON_SRC))
|
||||||
TESTBOUND_OBJ=$(addprefix $(BUILD),$(TESTBOUND_SRC:.c=.o)) $(COMPAT_OBJ)
|
TESTBOUND_OBJ=$(addprefix $(BUILD),$(TESTBOUND_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
LOCKVERIFY_SRC=testcode/lock_verify.c $(COMMON_SRC)
|
LOCKVERIFY_SRC=testcode/lock_verify.c checkconf/worker_cb.c $(COMMON_SRC)
|
||||||
LOCKVERIFY_OBJ=$(addprefix $(BUILD),$(LOCKVERIFY_SRC:.c=.o)) $(COMPAT_OBJ)
|
LOCKVERIFY_OBJ=$(addprefix $(BUILD),$(LOCKVERIFY_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
PKTVIEW_SRC=testcode/pktview.c testcode/readhex.c $(COMMON_SRC)
|
PKTVIEW_SRC=testcode/pktview.c testcode/readhex.c checkconf/worker_cb.c \
|
||||||
|
$(COMMON_SRC)
|
||||||
PKTVIEW_OBJ=$(addprefix $(BUILD),$(PKTVIEW_SRC:.c=.o)) $(COMPAT_OBJ)
|
PKTVIEW_OBJ=$(addprefix $(BUILD),$(PKTVIEW_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
SIGNIT_SRC=testcode/signit.c $(COMMON_SRC)
|
SIGNIT_SRC=testcode/signit.c checkconf/worker_cb.c $(COMMON_SRC)
|
||||||
SIGNIT_OBJ=$(addprefix $(BUILD),$(SIGNIT_SRC:.c=.o)) $(COMPAT_OBJ)
|
SIGNIT_OBJ=$(addprefix $(BUILD),$(SIGNIT_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
MEMSTATS_SRC=testcode/memstats.c $(COMMON_SRC)
|
MEMSTATS_SRC=testcode/memstats.c checkconf/worker_cb.c $(COMMON_SRC)
|
||||||
MEMSTATS_OBJ=$(addprefix $(BUILD),$(MEMSTATS_SRC:.c=.o)) $(COMPAT_OBJ)
|
MEMSTATS_OBJ=$(addprefix $(BUILD),$(MEMSTATS_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
||||||
$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) $(SIGNIT_SRC) \
|
$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) $(SIGNIT_SRC) \
|
||||||
|
|
|
||||||
67
checkconf/worker_cb.c
Normal file
67
checkconf/worker_cb.c
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* checkconf/worker_cb.c - fake callback routines to make fptr_wlist work
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is open source.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* This file contains fake callback functions, so that the symbols exist
|
||||||
|
* and the fptr_wlist continues to work even if the daemon/worker is not
|
||||||
|
* linked into the resulting program.
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
struct comm_reply;
|
||||||
|
struct comm_point;
|
||||||
|
|
||||||
|
int worker_handle_control_cmd(struct comm_point* ATTR_UNUSED(c),
|
||||||
|
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
|
||||||
|
struct comm_reply* ATTR_UNUSED(reply_info))
|
||||||
|
{
|
||||||
|
log_assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int worker_handle_request(struct comm_point* ATTR_UNUSED(c),
|
||||||
|
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
|
||||||
|
struct comm_reply* ATTR_UNUSED(repinfo))
|
||||||
|
{
|
||||||
|
log_assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
|
||||||
|
{
|
||||||
|
log_assert(0);
|
||||||
|
}
|
||||||
|
|
@ -111,7 +111,8 @@ checkrlimits(struct config_file* cfg)
|
||||||
|
|
||||||
/** to changedir, logfile */
|
/** to changedir, logfile */
|
||||||
static void
|
static void
|
||||||
apply_dir(struct daemon* daemon, struct config_file* cfg, int cmdline_verbose)
|
apply_dir(struct daemon* daemon, struct config_file* cfg, int cmdline_verbose,
|
||||||
|
int debug_mode)
|
||||||
{
|
{
|
||||||
/* apply if they have changed */
|
/* apply if they have changed */
|
||||||
daemon->cfg = cfg;
|
daemon->cfg = cfg;
|
||||||
|
|
@ -127,6 +128,9 @@ apply_dir(struct daemon* daemon, struct config_file* cfg, int cmdline_verbose)
|
||||||
log_err("cwd: malloc failed");
|
log_err("cwd: malloc failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!debug_mode) {
|
||||||
|
log_init(cfg->logfile, cfg->use_syslog);
|
||||||
|
}
|
||||||
if(!daemon->env->msg_cache ||
|
if(!daemon->env->msg_cache ||
|
||||||
cfg->msg_cache_size != slabhash_get_size(daemon->env->msg_cache) ||
|
cfg->msg_cache_size != slabhash_get_size(daemon->env->msg_cache) ||
|
||||||
cfg->msg_cache_slabs != daemon->env->msg_cache->size) {
|
cfg->msg_cache_slabs != daemon->env->msg_cache->size) {
|
||||||
|
|
@ -321,7 +325,7 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||||
fatal_exit("Could not alloc config defaults");
|
fatal_exit("Could not alloc config defaults");
|
||||||
if(!config_read(cfg, cfgfile))
|
if(!config_read(cfg, cfgfile))
|
||||||
fatal_exit("Could not read config file: %s", cfgfile);
|
fatal_exit("Could not read config file: %s", cfgfile);
|
||||||
apply_dir(daemon, cfg, cmdline_verbose);
|
apply_dir(daemon, cfg, cmdline_verbose, debug_mode);
|
||||||
|
|
||||||
/* prepare */
|
/* prepare */
|
||||||
if(!daemon_open_shared_ports(daemon))
|
if(!daemon_open_shared_ports(daemon))
|
||||||
|
|
|
||||||
|
|
@ -286,13 +286,7 @@ worker_check_request(ldns_buffer* pkt, struct worker* worker)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** process control messages from the main thread.
|
int
|
||||||
* @param c: comm point to read from.
|
|
||||||
* @param arg: worker.
|
|
||||||
* @param error: error status of comm point.
|
|
||||||
* @param reply_info: not used.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
worker_handle_control_cmd(struct comm_point* c, void* arg, int error,
|
worker_handle_control_cmd(struct comm_point* c, void* arg, int error,
|
||||||
struct comm_reply* ATTR_UNUSED(reply_info))
|
struct comm_reply* ATTR_UNUSED(reply_info))
|
||||||
{
|
{
|
||||||
|
|
@ -655,8 +649,7 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** handles callbacks from listening event interface */
|
int
|
||||||
static int
|
|
||||||
worker_handle_request(struct comm_point* c, void* arg, int error,
|
worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||||
struct comm_reply* repinfo)
|
struct comm_reply* repinfo)
|
||||||
{
|
{
|
||||||
|
|
@ -793,7 +786,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** worker signal callback */
|
|
||||||
void
|
void
|
||||||
worker_sighandler(int sig, void* arg)
|
worker_sighandler(int sig, void* arg)
|
||||||
{
|
{
|
||||||
|
|
@ -901,10 +893,12 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||||
(((unsigned int)worker->thread_num)<<17);
|
(((unsigned int)worker->thread_num)<<17);
|
||||||
/* shift thread_num so it does not match out pid bits */
|
/* shift thread_num so it does not match out pid bits */
|
||||||
if(!ub_initstate(seed, worker->rndstate, RND_STATE_SIZE)) {
|
if(!ub_initstate(seed, worker->rndstate, RND_STATE_SIZE)) {
|
||||||
|
seed = 0;
|
||||||
log_err("could not init random numbers.");
|
log_err("could not init random numbers.");
|
||||||
worker_delete(worker);
|
worker_delete(worker);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
seed = 0;
|
||||||
worker->front = listen_create(worker->base, ports,
|
worker->front = listen_create(worker->base, ports,
|
||||||
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
|
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
|
||||||
worker_handle_request, worker);
|
worker_handle_request, worker);
|
||||||
|
|
|
||||||
|
|
@ -192,4 +192,18 @@ struct outbound_entry* worker_send_query(uint8_t* qname, size_t qnamelen,
|
||||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||||
struct module_qstate* q);
|
struct module_qstate* q);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* process control messages from the main thread.
|
||||||
|
* @param c: comm point to read from.
|
||||||
|
* @param arg: worker.
|
||||||
|
* @param error: error status of comm point.
|
||||||
|
* @param reply_info: not used.
|
||||||
|
*/
|
||||||
|
int worker_handle_control_cmd(struct comm_point* c, void* arg, int error,
|
||||||
|
struct comm_reply* reply_info);
|
||||||
|
|
||||||
|
/** handles callbacks from listening event interface */
|
||||||
|
int worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||||
|
struct comm_reply* repinfo);
|
||||||
|
|
||||||
#endif /* DAEMON_WORKER_H */
|
#endif /* DAEMON_WORKER_H */
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
4 October 2007: Wouter
|
||||||
|
- overwrite sensitive random seed value after use.
|
||||||
|
- switch to logfile very soon if not -d (console attached).
|
||||||
|
- error messages do not reveal the trustanchor contents.
|
||||||
|
- start work on function pointer whitelists.
|
||||||
|
|
||||||
3 October 2007: Wouter
|
3 October 2007: Wouter
|
||||||
- fix for multiple empty nonterminals, after multiple DSes in the
|
- fix for multiple empty nonterminals, after multiple DSes in the
|
||||||
chain of trust.
|
chain of trust.
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ described in
|
||||||
.Xr unbound.conf 5 .
|
.Xr unbound.conf 5 .
|
||||||
.It Fl d
|
.It Fl d
|
||||||
Debug flag, do not fork into the background, but stay attached to the
|
Debug flag, do not fork into the background, but stay attached to the
|
||||||
console.
|
console. This flag will also delay writing to the logfile until the
|
||||||
|
thread-spawn time. So that most config and setup errors appear on stderr.
|
||||||
.It Fl v
|
.It Fl v
|
||||||
Increase verbosity. If given multiple times, more information is logged.
|
Increase verbosity. If given multiple times, more information is logged.
|
||||||
This is in addition to the verbosity (if any) from the config file.
|
This is in addition to the verbosity (if any) from the config file.
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,8 @@ If "" is given, logging goes to stderr, or nowhere once daemonized.
|
||||||
The logfile is appended to, in the following format:
|
The logfile is appended to, in the following format:
|
||||||
[seconds since 1970] unbound[pid:tid]: type: message.
|
[seconds since 1970] unbound[pid:tid]: type: message.
|
||||||
If this option is given, the use-syslog is option is set to "no".
|
If this option is given, the use-syslog is option is set to "no".
|
||||||
|
The logfile is reopened (for append) when the config file is reread, on
|
||||||
|
SIGHUP.
|
||||||
.It \fBuse-syslog:\fR <yes or no>
|
.It \fBuse-syslog:\fR <yes or no>
|
||||||
Sets unbound to send log messages to the syslogd, using
|
Sets unbound to send log messages to the syslogd, using
|
||||||
.Xr syslog 3 .
|
.Xr syslog 3 .
|
||||||
|
|
|
||||||
|
|
@ -219,8 +219,7 @@ outnet_tcp_cb(struct comm_point* c, void* arg, int error,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** callback for incoming udp answers from the network */
|
int
|
||||||
static int
|
|
||||||
outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||||
struct comm_reply *reply_info)
|
struct comm_reply *reply_info)
|
||||||
{
|
{
|
||||||
|
|
@ -381,8 +380,7 @@ calc_num46(char** ifs, int num_ifs, int do_ip4, int do_ip6,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** callback for udp timeout */
|
void
|
||||||
static void
|
|
||||||
pending_udp_timer_cb(void *arg)
|
pending_udp_timer_cb(void *arg)
|
||||||
{
|
{
|
||||||
struct pending* p = (struct pending*)arg;
|
struct pending* p = (struct pending*)arg;
|
||||||
|
|
@ -709,8 +707,7 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||||
return pend;
|
return pend;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** callback for outgoing TCP timer event */
|
void
|
||||||
static void
|
|
||||||
outnet_tcptimer(void* arg)
|
outnet_tcptimer(void* arg)
|
||||||
{
|
{
|
||||||
struct waiting_tcp* w = (struct waiting_tcp*)arg;
|
struct waiting_tcp* w = (struct waiting_tcp*)arg;
|
||||||
|
|
|
||||||
|
|
@ -369,4 +369,14 @@ size_t outnet_get_mem(struct outside_network* outnet);
|
||||||
*/
|
*/
|
||||||
size_t serviced_get_mem(struct serviced_query* sq);
|
size_t serviced_get_mem(struct serviced_query* sq);
|
||||||
|
|
||||||
|
/** callback for incoming udp answers from the network */
|
||||||
|
int outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||||
|
struct comm_reply *reply_info);
|
||||||
|
|
||||||
|
/** callback for udp timeout */
|
||||||
|
void pending_udp_timer_cb(void *arg);
|
||||||
|
|
||||||
|
/** callback for outgoing TCP timer event */
|
||||||
|
void outnet_tcptimer(void* arg);
|
||||||
|
|
||||||
#endif /* OUTSIDE_NETWORK_H */
|
#endif /* OUTSIDE_NETWORK_H */
|
||||||
|
|
|
||||||
|
|
@ -959,4 +959,23 @@ size_t serviced_get_mem(struct serviced_query* ATTR_UNUSED(c))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fake for fptr wlist */
|
||||||
|
int outnet_udp_cb(struct comm_point* ATTR_UNUSED(c),
|
||||||
|
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
|
||||||
|
struct comm_reply *ATTR_UNUSED(reply_info))
|
||||||
|
{
|
||||||
|
log_assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pending_udp_timer_cb(void *ATTR_UNUSED(arg))
|
||||||
|
{
|
||||||
|
log_assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void outnet_tcptimer(void* ATTR_UNUSED(arg))
|
||||||
|
{
|
||||||
|
log_assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
/*********** End of Dummy routines ***********/
|
/*********** End of Dummy routines ***********/
|
||||||
|
|
|
||||||
79
util/fptr_wlist.c
Normal file
79
util/fptr_wlist.c
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* util/fptr_wlist.c - function pointer whitelists.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is open source.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* This file contains functions that check function pointers.
|
||||||
|
* The functions contain a whitelist of known good callback values.
|
||||||
|
* Any other values lead to an error.
|
||||||
|
*
|
||||||
|
* Due to the listing nature, this file violates all the modularization
|
||||||
|
* boundaries in the program.
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
#include "util/fptr_wlist.h"
|
||||||
|
#include "daemon/worker.h"
|
||||||
|
#include "services/outside_network.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
fptr_whitelist_comm_point(comm_point_callback_t *fptr)
|
||||||
|
{
|
||||||
|
if(fptr == &worker_handle_control_cmd) return 1;
|
||||||
|
else if(fptr == &worker_handle_request) return 1;
|
||||||
|
else if(fptr == &outnet_udp_cb) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fptr_whitelist_comm_timer(void (*fptr)(void*))
|
||||||
|
{
|
||||||
|
if(fptr == &pending_udp_timer_cb) return 1;
|
||||||
|
else if(fptr == &outnet_tcptimer) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fptr_whitelist_comm_signal(void (*fptr)(int, void*))
|
||||||
|
{
|
||||||
|
if(fptr == &worker_sighandler) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fptr_whitelist_event(void (*fptr)(int, short, void *))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
90
util/fptr_wlist.h
Normal file
90
util/fptr_wlist.h
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* util/fptr_wlist.h - function pointer whitelists.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is open source.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* This file contains functions that check function pointers.
|
||||||
|
* The functions contain a whitelist of known good callback values.
|
||||||
|
* Any other values lead to an error.
|
||||||
|
*
|
||||||
|
* This prevent heap overflow based exploits, where the callback pointer
|
||||||
|
* is overwritten by a buffer overflow (apart from this defense, buffer
|
||||||
|
* overflows should be fixed of course).
|
||||||
|
*
|
||||||
|
* Function pointers are used in
|
||||||
|
* o network code callbacks.
|
||||||
|
* o rbtree, lruhash, region data manipulation
|
||||||
|
* o module operations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UTIL_FPTR_WLIST_H
|
||||||
|
#define UTIL_FPTR_WLIST_H
|
||||||
|
#include "util/netevent.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check function pointer whitelist for comm_point callback values.
|
||||||
|
*
|
||||||
|
* @param fptr: function pointer to check.
|
||||||
|
* @return false if not in whitelist.
|
||||||
|
*/
|
||||||
|
int fptr_whitelist_comm_point(comm_point_callback_t *fptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check function pointer whitelist for comm_timer callback values.
|
||||||
|
*
|
||||||
|
* @param fptr: function pointer to check.
|
||||||
|
* @return false if not in whitelist.
|
||||||
|
*/
|
||||||
|
int fptr_whitelist_comm_timer(void (*fptr)(void*));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check function pointer whitelist for comm_signal callback values.
|
||||||
|
*
|
||||||
|
* @param fptr: function pointer to check.
|
||||||
|
* @return false if not in whitelist.
|
||||||
|
*/
|
||||||
|
int fptr_whitelist_comm_signal(void (*fptr)(int, void*));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check function pointer whitelist for event structure callback values.
|
||||||
|
* This is not called by libevent itself, but checked by netevent.
|
||||||
|
*
|
||||||
|
* @param fptr: function pointer to check.
|
||||||
|
* @return false if not in whitelist.
|
||||||
|
*/
|
||||||
|
int fptr_whitelist_event(void (*fptr)(int, short, void *));
|
||||||
|
|
||||||
|
#endif /* UTIL_FPTR_WLIST_H */
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
#include "util/netevent.h"
|
#include "util/netevent.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
#include "util/fptr_wlist.h"
|
||||||
|
|
||||||
/* -------- Start of local definitions -------- */
|
/* -------- Start of local definitions -------- */
|
||||||
/** The TCP reading or writing query timeout in seconds */
|
/** The TCP reading or writing query timeout in seconds */
|
||||||
|
|
@ -247,6 +248,7 @@ comm_point_udp_callback(int fd, short event, void* arg)
|
||||||
}
|
}
|
||||||
ldns_buffer_skip(rep.c->buffer, recv);
|
ldns_buffer_skip(rep.c->buffer, recv);
|
||||||
ldns_buffer_flip(rep.c->buffer);
|
ldns_buffer_flip(rep.c->buffer);
|
||||||
|
log_assert(fptr_whitelist_comm_point(rep.c->callback));
|
||||||
if((*rep.c->callback)(rep.c, rep.c->cb_arg, NETEVENT_NOERROR, &rep)) {
|
if((*rep.c->callback)(rep.c, rep.c->cb_arg, NETEVENT_NOERROR, &rep)) {
|
||||||
/* send back immediate reply */
|
/* send back immediate reply */
|
||||||
(void)comm_point_send_udp_msg(rep.c, rep.c->buffer,
|
(void)comm_point_send_udp_msg(rep.c, rep.c->buffer,
|
||||||
|
|
@ -356,6 +358,7 @@ tcp_callback_reader(struct comm_point* c)
|
||||||
comm_point_stop_listening(c);
|
comm_point_stop_listening(c);
|
||||||
rep.c = c;
|
rep.c = c;
|
||||||
rep.addrlen = 0;
|
rep.addrlen = 0;
|
||||||
|
log_assert(fptr_whitelist_comm_point(c->callback));
|
||||||
if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &rep) ) {
|
if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &rep) ) {
|
||||||
comm_point_start_listening(c, -1, TCP_QUERY_TIMEOUT);
|
comm_point_start_listening(c, -1, TCP_QUERY_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
@ -502,27 +505,35 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
|
||||||
if(event&EV_READ) {
|
if(event&EV_READ) {
|
||||||
if(!comm_point_tcp_handle_read(fd, c, 0)) {
|
if(!comm_point_tcp_handle_read(fd, c, 0)) {
|
||||||
reclaim_tcp_handler(c);
|
reclaim_tcp_handler(c);
|
||||||
if(!c->tcp_do_close)
|
if(!c->tcp_do_close) {
|
||||||
|
log_assert(fptr_whitelist_comm_point(
|
||||||
|
c->callback));
|
||||||
(void)(*c->callback)(c, c->cb_arg,
|
(void)(*c->callback)(c, c->cb_arg,
|
||||||
NETEVENT_CLOSED, NULL);
|
NETEVENT_CLOSED, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(event&EV_WRITE) {
|
if(event&EV_WRITE) {
|
||||||
if(!comm_point_tcp_handle_write(fd, c)) {
|
if(!comm_point_tcp_handle_write(fd, c)) {
|
||||||
reclaim_tcp_handler(c);
|
reclaim_tcp_handler(c);
|
||||||
if(!c->tcp_do_close)
|
if(!c->tcp_do_close) {
|
||||||
|
log_assert(fptr_whitelist_comm_point(
|
||||||
|
c->callback));
|
||||||
(void)(*c->callback)(c, c->cb_arg,
|
(void)(*c->callback)(c, c->cb_arg,
|
||||||
NETEVENT_CLOSED, NULL);
|
NETEVENT_CLOSED, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(event&EV_TIMEOUT) {
|
if(event&EV_TIMEOUT) {
|
||||||
verbose(VERB_DETAIL, "tcp took too long, dropped");
|
verbose(VERB_DETAIL, "tcp took too long, dropped");
|
||||||
reclaim_tcp_handler(c);
|
reclaim_tcp_handler(c);
|
||||||
if(!c->tcp_do_close)
|
if(!c->tcp_do_close) {
|
||||||
|
log_assert(fptr_whitelist_comm_point(c->callback));
|
||||||
(void)(*c->callback)(c, c->cb_arg,
|
(void)(*c->callback)(c, c->cb_arg,
|
||||||
NETEVENT_TIMEOUT, NULL);
|
NETEVENT_TIMEOUT, NULL);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log_err("Ignored event %d for tcphdl.", event);
|
log_err("Ignored event %d for tcphdl.", event);
|
||||||
|
|
@ -535,6 +546,7 @@ static void comm_point_local_handle_callback(int fd, short event, void* arg)
|
||||||
|
|
||||||
if(event&EV_READ) {
|
if(event&EV_READ) {
|
||||||
if(!comm_point_tcp_handle_read(fd, c, 1)) {
|
if(!comm_point_tcp_handle_read(fd, c, 1)) {
|
||||||
|
log_assert(fptr_whitelist_comm_point(c->callback));
|
||||||
(void)(*c->callback)(c, c->cb_arg, NETEVENT_CLOSED,
|
(void)(*c->callback)(c, c->cb_arg, NETEVENT_CLOSED,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -1064,6 +1076,7 @@ comm_timer_callback(int ATTR_UNUSED(fd), short event, void* arg)
|
||||||
if(!(event&EV_TIMEOUT))
|
if(!(event&EV_TIMEOUT))
|
||||||
return;
|
return;
|
||||||
tm->ev_timer->enabled = 0;
|
tm->ev_timer->enabled = 0;
|
||||||
|
log_assert(fptr_whitelist_comm_timer(tm->callback));
|
||||||
(*tm->callback)(tm->cb_arg);
|
(*tm->callback)(tm->cb_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1102,6 +1115,7 @@ comm_signal_callback(int sig, short event, void* arg)
|
||||||
struct comm_signal* comsig = (struct comm_signal*)arg;
|
struct comm_signal* comsig = (struct comm_signal*)arg;
|
||||||
if(!(event & EV_SIGNAL))
|
if(!(event & EV_SIGNAL))
|
||||||
return;
|
return;
|
||||||
|
log_assert(fptr_whitelist_comm_signal(comsig->callback));
|
||||||
(*comsig->callback)(sig, comsig->cb_arg);
|
(*comsig->callback)(sig, comsig->cb_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -496,8 +496,8 @@ skip_to_special(FILE* in, ldns_buffer* buf, int* line, int spec)
|
||||||
}
|
}
|
||||||
if(rdlen != 1 || *ldns_buffer_begin(buf) != (uint8_t)spec) {
|
if(rdlen != 1 || *ldns_buffer_begin(buf) != (uint8_t)spec) {
|
||||||
ldns_buffer_write_u8(buf, 0);
|
ldns_buffer_write_u8(buf, 0);
|
||||||
log_err("trusted-keys, line %d, expected %c got %s",
|
log_err("trusted-keys, line %d, expected %c",
|
||||||
*line, spec, ldns_buffer_begin(buf));
|
*line, spec);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -544,8 +544,7 @@ process_bind_contents(struct val_anchors* anchors, ldns_buffer* buf,
|
||||||
ldns_buffer_skip(buf, -1);
|
ldns_buffer_skip(buf, -1);
|
||||||
if(contnum > 0 && quoted) {
|
if(contnum > 0 && quoted) {
|
||||||
if(ldns_buffer_remaining(buf) < 8+1) {
|
if(ldns_buffer_remaining(buf) < 8+1) {
|
||||||
log_err("line %d, too long, %s",
|
log_err("line %d, too long", *line);
|
||||||
*line, ldns_buffer_begin(buf));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ldns_buffer_write(buf, " DNSKEY ", 8);
|
ldns_buffer_write(buf, " DNSKEY ", 8);
|
||||||
|
|
@ -558,8 +557,7 @@ process_bind_contents(struct val_anchors* anchors, ldns_buffer* buf,
|
||||||
|
|
||||||
if(contnum < 5) {
|
if(contnum < 5) {
|
||||||
ldns_buffer_write_u8(buf, 0);
|
ldns_buffer_write_u8(buf, 0);
|
||||||
log_err("line %d, bad key, %s",
|
log_err("line %d, bad key", *line);
|
||||||
*line, ldns_buffer_begin(buf));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ldns_buffer_skip(buf, -1);
|
ldns_buffer_skip(buf, -1);
|
||||||
|
|
@ -570,7 +568,7 @@ process_bind_contents(struct val_anchors* anchors, ldns_buffer* buf,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!anchor_store_str(anchors, buf, str)) {
|
if(!anchor_store_str(anchors, buf, str)) {
|
||||||
log_err("line %d, bad key, %s", *line, str);
|
log_err("line %d, bad key", *line);
|
||||||
free(str);
|
free(str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -583,8 +581,7 @@ process_bind_contents(struct val_anchors* anchors, ldns_buffer* buf,
|
||||||
} else if(rdlen == 1 && ldns_buffer_current(buf)[-1] == '}') {
|
} else if(rdlen == 1 && ldns_buffer_current(buf)[-1] == '}') {
|
||||||
if(contnum > 0) {
|
if(contnum > 0) {
|
||||||
ldns_buffer_write_u8(buf, 0);
|
ldns_buffer_write_u8(buf, 0);
|
||||||
log_err("line %d, bad key before }, %s",
|
log_err("line %d, bad key before }", *line);
|
||||||
*line, ldns_buffer_begin(buf));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -596,8 +593,7 @@ process_bind_contents(struct val_anchors* anchors, ldns_buffer* buf,
|
||||||
contnum ++;
|
contnum ++;
|
||||||
if(contnum == 1 && !quoted) {
|
if(contnum == 1 && !quoted) {
|
||||||
if(ldns_buffer_remaining(buf) < 8+1) {
|
if(ldns_buffer_remaining(buf) < 8+1) {
|
||||||
log_err("line %d, too long, %s",
|
log_err("line %d, too long", *line);
|
||||||
*line, ldns_buffer_begin(buf));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ldns_buffer_write(buf, " DNSKEY ", 8);
|
ldns_buffer_write(buf, " DNSKEY ", 8);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue