Bug 544 - Unbound running with only iterator segfaults on 'unbound-control forward_add +i <domain> <ip>'
Unbound running with only iterator segfaults on 'unbound-control forward_add ...
Status: RESOLVED FIXED
Product: unbound
Classification: Unclassified
Component: server
1.4.20
Other Linux
: P5 critical
Assigned To: unbound team
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2014-01-16 13:27 CET by Tomas Hozza
Modified: 2014-01-16 14:04 CET (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tomas Hozza 2014-01-16 13:27:33 CET
Hi.

I recently run into a bug in the unbound. I was experimenting with unbound
running without validator module - so only with the iterator module. And
when I called 'unbound-control forward_add +i <domain> <ip>' unbound ended with
segfault.

# gdb unbound
GNU gdb (GDB) Fedora 7.6.50.20130731-16.fc20
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
..
Reading symbols from /usr/sbin/unbound...Reading symbols from /usr/lib/debug/usr/sbin/unbound.debug...done.
done.
(gdb) run -d
Starting program: /usr/sbin/unbound -d
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Jan 16 13:02:41 unbound[6951:0] warning: increased limit(open files) from 1024 to 8290
[New Thread 0x7f689f961700 (LWP 6978)]

Program received signal SIGSEGV, Segmentation fault.
__GI___pthread_mutex_lock (mutex=mutex@entry=0x0) at ../nptl/pthread_mutex_lock.c:66
66	  unsigned int type = PTHREAD_MUTEX_TYPE_ELISION (mutex);
(gdb) bt
#0  __GI___pthread_mutex_lock (mutex=mutex@entry=0x0) at ../nptl/pthread_mutex_lock.c:66
#1  0x00007f68a31b7477 in anchors_add_insecure (anchors=0x0, nm=0x7f68a439d780 "\006google\003com", c=1) at validator/val_anchor.c:1215
#2  0x00007f68a31fbf0a in do_forward_add (args=<optimized out>, worker=0x7f68a3d18580, ssl=0x7f68a43892e0) at daemon/remote.c:1575
#3  execute_cmd.8233 (rc=rc@entry=0x7f68a3d0d620, ssl=ssl@entry=0x7f68a43892e0, cmd=cmd@entry=0x7fff5b6e1600 " forward_add +i", worker=0x7f68a3d18580) at daemon/remote.c:2078
#4  0x00007f68a3203560 in handle_req.isra.16 (rc=rc@entry=0x7f68a3d0d620, ssl=0x7f68a43892e0) at daemon/remote.c:2217
#5  0x00007f68a32036f3 in remote_control_callback (c=<optimized out>, arg=0x7f68a4387c00, err=<optimized out>, rep=<optimized out>) at daemon/remote.c:2284
#6  0x00007f68a286aa44 in event_process_active_single_queue (activeq=0x7f68a3d1be00, base=0x7f68a3d1b9e0) at event.c:1350
#7  event_process_active (base=<optimized out>) at event.c:1420
#8  event_base_loop (base=0x7f68a3d1b9e0, flags=flags@entry=0) at event.c:1621
#9  0x00007f68a286b7d7 in event_base_dispatch (event_base=<optimized out>) at event.c:1450
#10 0x00007f68a31c5b6c in comm_base_dispatch (b=<optimized out>) at util/netevent.c:271
#11 0x00007f68a31b1d14 in worker_work (worker=<optimized out>) at daemon/worker.c:1216
#12 daemon_fork (daemon=daemon@entry=0x7f68a3cc6030) at daemon/daemon.c:493
#13 0x00007f68a31a03fb in run_daemon (debug_mode=1, cmdline_verbose=0, cfgfile=0x7f68a322e1cf "/etc/unbound/unbound.conf") at daemon/unbound.c:666
#14 main (argc=<optimized out>, argv=<optimized out>) at daemon/unbound.c:761
(gdb) l
61	__pthread_mutex_lock (mutex)
62	     pthread_mutex_t *mutex;
63	{
64	  assert (sizeof (mutex->__size) >= sizeof (mutex->__data));
65	
66	  unsigned int type = PTHREAD_MUTEX_TYPE_ELISION (mutex);
67	
68	  LIBC_PROBE (mutex_entry, 1, mutex);
69	
70	  if (__builtin_expect (type & ~(PTHREAD_MUTEX_KIND_MASK_NP
(gdb) p mutex
$1 = (pthread_mutex_t *) 0x0
(gdb) p *mutex
Cannot access memory at address 0x0
(gdb) up
#1  0x00007f68a31b7477 in anchors_add_insecure (anchors=0x0, nm=0x7f68a439d780 "\006google\003com", c=1) at validator/val_anchor.c:1215
1215		lock_basic_lock(&anchors->lock);
(gdb) l
1210		struct trust_anchor key;
1211		key.node.key = &key;
1212		key.name = nm;
1213		key.namelabs = dname_count_size_labels(nm, &key.namelen);
1214		key.dclass = c;
1215		lock_basic_lock(&anchors->lock);
1216		if(rbtree_search(anchors->tree, &key)) {
1217			lock_basic_unlock(&anchors->lock);
1218			/* nothing to do, already an anchor or insecure point */
1219			return 1;
(gdb) p anchors
$2 = (struct val_anchors *) 0x0
(gdb) up
#2  0x00007f68a31fbf0a in do_forward_add (args=<optimized out>, worker=0x7f68a3d18580, ssl=0x7f68a43892e0) at daemon/remote.c:1575
1575			if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN,
(gdb) p worker
$3 = (struct worker *) 0x7f68a3d18580
(gdb) p *worker
$4 = {thread_num = 0, daemon = 0x7f68a3cc6030, thr_id = 0, cmd = 0x7f68a3d13c50, base = 0x7f68a3d1b8c0, front = 0x7f68a3d1cae0, back = 0x7f68a3d1fe40, ports = 0x7f68a3d68e90, 
  numports = 16384, comsig = 0x7f68a3d1b9b0, cmd_com = 0x0, stat_timer = 0x7f68a41c6b80, rndstate = 0x7f68a3d19a60, need_to_exit = 0, alloc = {lock = 0, 
    super = 0x7f68a3cc60a0, quar = 0x0, num_quar = 0, thread_num = 0, next_id = 1, last_id = 281474976710655, cleanup = 0x7f68a31ddae0 <worker_alloc_cleanup>, 
    cleanup_arg = 0x7f68a3d18580, max_reg_blocks = 100, num_reg_blocks = 100, reg_list = 0x7f68a4363290}, stats = {num_queries = 0, num_queries_missed_cache = 0, 
    num_queries_prefetch = 0, sum_query_list_size = 0, max_query_list_size = 0, extended = 1, qtype = {0 <repeats 256 times>}, qtype_big = 0, qclass = {
      0 <repeats 256 times>}, qclass_big = 0, qopcode = {0 <repeats 16 times>}, qtcp = 0, qipv6 = 0, qbit_QR = 0, qbit_AA = 0, qbit_TC = 0, qbit_RD = 0, qbit_RA = 0, 
    qbit_Z = 0, qbit_AD = 0, qbit_CD = 0, qEDNS = 0, qEDNS_DO = 0, ans_rcode = {0 <repeats 16 times>}, ans_rcode_nodata = 0, ans_secure = 0, ans_bogus = 0, rrset_bogus = 0, 
    unwanted_replies = 0, unwanted_queries = 0, hist = {0 <repeats 40 times>}}, scratchpad = 0x7f68a41c6c40, env = {cfg = 0x7f68a3ce2bb0, msg_cache = 0x7f68a3ce7c90, 
    rrset_cache = 0x7f68a3cec090, infra_cache = 0x7f68a3cec0b0, key_cache = 0x0, send_query = 0x7f68a31dc5a0 <worker_send_query>, 
    detach_subs = 0x7f68a3201c00 <mesh_detach_subs>, attach_sub = 0x7f68a3202ff0 <mesh_attach_sub>, kill_sub = 0x7f68a31aead0 <mesh_state_delete>, detect_cycle = 
    0x7f68a31f02c0 <mesh_detect_cycle>, scratch = 0x7f68a41c6c40, scratch_buffer = 0x7f68a4377ae0, worker = 0x7f68a3d18580, mesh = 0x7f68a43672a0, alloc = 0x7f68a3d185f0, 
    rnd = 0x7f68a3d19a60, now = 0x7f68a3d1b8f8, now_tv = 0x7f68a3d1b900, need_to_validate = 0, anchors = 0x0, neg_cache = 0x0, probe_timer = 0x0, fwds = 0x7f68a4387b30, 
    hints = 0x7f68a4387b70, modinfo = {0x7f68a3d11a60, 0x0, 0x0, 0x0, 0x0}}}
(gdb) p *worker->env
Structure has no component named operator*.
(gdb) p *worker.env
Structure has no component named operator*.
(gdb) p worker->env
$5 = {cfg = 0x7f68a3ce2bb0, msg_cache = 0x7f68a3ce7c90, rrset_cache = 0x7f68a3cec090, infra_cache = 0x7f68a3cec0b0, key_cache = 0x0, send_query = 
    0x7f68a31dc5a0 <worker_send_query>, detach_subs = 0x7f68a3201c00 <mesh_detach_subs>, attach_sub = 0x7f68a3202ff0 <mesh_attach_sub>, 
  kill_sub = 0x7f68a31aead0 <mesh_state_delete>, detect_cycle = 0x7f68a31f02c0 <mesh_detect_cycle>, scratch = 0x7f68a41c6c40, scratch_buffer = 0x7f68a4377ae0, 
  worker = 0x7f68a3d18580, mesh = 0x7f68a43672a0, alloc = 0x7f68a3d185f0, rnd = 0x7f68a3d19a60, now = 0x7f68a3d1b8f8, now_tv = 0x7f68a3d1b900, need_to_validate = 0, 
  anchors = 0x0, neg_cache = 0x0, probe_timer = 0x0, fwds = 0x7f68a4387b30, hints = 0x7f68a4387b70, modinfo = {0x7f68a3d11a60, 0x0, 0x0, 0x0, 0x0}}
(gdb) up
#3  execute_cmd.8233 (rc=rc@entry=0x7f68a3d0d620, ssl=ssl@entry=0x7f68a43892e0, cmd=cmd@entry=0x7fff5b6e1600 " forward_add +i", worker=0x7f68a3d18580) at daemon/remote.c:2078
2078			do_forward_add(ssl, worker, skipwhite(p+11));
(gdb) l
2073			do_stub_remove(ssl, worker, skipwhite(p+11));
2074			return;
2075		} else if(cmdcmp(p, "forward_add", 11)) {
2076			/* must always distribute this cmd */
2077			if(rc) distribute_cmd(rc, ssl, cmd);
2078			do_forward_add(ssl, worker, skipwhite(p+11));
2079			return;
2080		} else if(cmdcmp(p, "forward_remove", 14)) {
2081			/* must always distribute this cmd */
2082			if(rc) distribute_cmd(rc, ssl, cmd);
(gdb) p worker
$6 = (struct worker *) 0x7f68a3d18580
(gdb) p worker->env
$7 = {cfg = 0x7f68a3ce2bb0, msg_cache = 0x7f68a3ce7c90, rrset_cache = 0x7f68a3cec090, infra_cache = 0x7f68a3cec0b0, key_cache = 0x0, send_query = 
    0x7f68a31dc5a0 <worker_send_query>, detach_subs = 0x7f68a3201c00 <mesh_detach_subs>, attach_sub = 0x7f68a3202ff0 <mesh_attach_sub>, 
  kill_sub = 0x7f68a31aead0 <mesh_state_delete>, detect_cycle = 0x7f68a31f02c0 <mesh_detect_cycle>, scratch = 0x7f68a41c6c40, scratch_buffer = 0x7f68a4377ae0, 
  worker = 0x7f68a3d18580, mesh = 0x7f68a43672a0, alloc = 0x7f68a3d185f0, rnd = 0x7f68a3d19a60, now = 0x7f68a3d1b8f8, now_tv = 0x7f68a3d1b900, need_to_validate = 0, 
  anchors = 0x0, neg_cache = 0x0, probe_timer = 0x0, fwds = 0x7f68a4387b30, hints = 0x7f68a4387b70, modinfo = {0x7f68a3d11a60, 0x0, 0x0, 0x0, 0x0}}
(gdb) up
#4  0x00007f68a3203560 in handle_req.isra.16 (rc=rc@entry=0x7f68a3d0d620, ssl=0x7f68a43892e0) at daemon/remote.c:2217
2217		execute_cmd(rc, ssl, buf, rc->worker);
(gdb) up
#5  0x00007f68a32036f3 in remote_control_callback (c=<optimized out>, arg=0x7f68a4387c00, err=<optimized out>, rep=<optimized out>) at daemon/remote.c:2284
2284		handle_req(rc, s, s->ssl);
(gdb) p s->rc->worker->env
$8 = {cfg = 0x7f68a3ce2bb0, msg_cache = 0x7f68a3ce7c90, rrset_cache = 0x7f68a3cec090, infra_cache = 0x7f68a3cec0b0, key_cache = 0x0, send_query = 
    0x7f68a31dc5a0 <worker_send_query>, detach_subs = 0x7f68a3201c00 <mesh_detach_subs>, attach_sub = 0x7f68a3202ff0 <mesh_attach_sub>, 
  kill_sub = 0x7f68a31aead0 <mesh_state_delete>, detect_cycle = 0x7f68a31f02c0 <mesh_detect_cycle>, scratch = 0x7f68a41c6c40, scratch_buffer = 0x7f68a4377ae0, 
  worker = 0x7f68a3d18580, mesh = 0x7f68a43672a0, alloc = 0x7f68a3d185f0, rnd = 0x7f68a3d19a60, now = 0x7f68a3d1b8f8, now_tv = 0x7f68a3d1b900, need_to_validate = 0, 
  anchors = 0x0, neg_cache = 0x0, probe_timer = 0x0, fwds = 0x7f68a4387b30, hints = 0x7f68a4387b70, modinfo = {0x7f68a3d11a60, 0x0, 0x0, 0x0, 0x0}}
(gdb) up
#6  0x00007f68a286aa44 in event_process_active_single_queue (activeq=0x7f68a3d1be00, base=0x7f68a3d1b9e0) at event.c:1350
1350				(*ev->ev_callback)(


The problem seems to be caused by the "+i" insecure option when calling
forward_add command. I know i does not make sense when validator is not
running, however unbound should not end with SIGSEGV in such a case.
Comment 1 Wouter Wijngaards 2014-01-16 14:04:49 CET
Hi Tomas,

I have fixed the bug in svn trunk, and I am working on a unit test for it.  Thank you for the report.

Best regards,
   Wouter