<div dir="ltr">In case it was missed on the packages Github feed.<br><div><br><div class="gmail_quote">---------- Forwarded message ----------<br>From: <b class="gmail_sendername">philipc</b> <span dir="ltr"><<a href="mailto:notifications@github.com">notifications@github.com</a>></span><br>Date: Fri, Jun 26, 2015 at 8:29 AM<br>Subject: [packages] netifd: NULL device on network restart (#1476)<br>To: openwrt/packages <<a href="mailto:packages@noreply.github.com">packages@noreply.github.com</a>><br><br><br><p>I'm getting a NULL device access in system_del_address() with the following test configuration:</p>

<pre><code>config interface net1
        option ifname eth0
        option proto static
        option ipaddr 10.1.1.1
        option netmask 255.255.255.255

config interface net2
        option ifname eth0
        option proto static
        option ipaddr 10.2.2.2
        option netmask 255.255.255.255
</code></pre>

<p>The NULL device access occurs when I call 'ubus call network restart'. Here's the backtrace:</p>

<pre><code>Program received signal SIGSEGV, Segmentation fault.
system_del_address (dev=dev@entry=0x0, addr=addr@entry=0x634d50) at /home/philipc/pkg/netifd/system-linux.c:1509
1509        return system_addr(dev, addr, RTM_DELADDR);
(gdb) bt
#0  system_del_address (dev=dev@entry=0x0, addr=addr@entry=0x634d50) at /home/philipc/pkg/netifd/system-linux.c:1509
#1  0x0000000000407d3e in interface_update_proto_addr (tree=<optimised out>, node_new=0x0, node_old=0x634d50)
    at /home/philipc/pkg/netifd/interface-ip.c:539
#2  0x00007ffff7bd6415 in vlist_flush (tree=tree@entry=0x633340) at /home/philipc/pkg/libubox/vlist.c:71
#3  0x00007ffff7bd642f in vlist_flush_all (tree=tree@entry=0x633340) at /home/philipc/pkg/libubox/vlist.c:79
#4  0x000000000040949c in interface_ip_flush (ip=ip@entry=0x633330) at /home/philipc/pkg/netifd/interface-ip.c:1301
#5  0x0000000000405456 in mark_interface_down (iface=iface@entry=0x6331b0)
    at /home/philipc/pkg/netifd/interface.c:243
#6  0x0000000000406645 in interface_proto_cb (state=<optimised out>, ev=<optimised out>)
    at /home/philipc/pkg/netifd/interface.c:678
#7  0x000000000040aa86 in interface_proto_event (proto=0x632ae0, cmd=cmd@entry=PROTO_CMD_TEARDOWN, 
    force=force@entry=false) at /home/philipc/pkg/netifd/proto.c:629
#8  0x00000000004054f6 in interface_check_state (iface=0x6331b0) at /home/philipc/pkg/netifd/interface.c:297
#9  0x000000000040c730 in device_broadcast_cb (ctx=0x0, list=0x0) at /home/philipc/pkg/netifd/device.c:287
#10 0x00007ffff7bd660e in safe_list_for_each (head=head@entry=0x633850, cb=cb@entry=0x40c715 <device_broadcast_cb>, 
    ctx=ctx@entry=0x7fffffffe35c) at /home/philipc/pkg/libubox/safe_list.c:74
#11 0x000000000040c819 in device_broadcast_event (dev=0x633810, ev=<optimised out>)
    at /home/philipc/pkg/netifd/device.c:296
#12 0x0000000000406d80 in interface_set_down (iface=0x633a30, iface@entry=0x0)
    at /home/philipc/pkg/netifd/interface.c:1020
#13 0x000000000040472e in netifd_restart () at /home/philipc/pkg/netifd/main.c:225
</code></pre>

<p>The problem is that when net1 is brought up, it also brings up all other interfaces using the same device, but device_claim(&iface->main_dev) is not called for these other interfaces.  Here's the part of the backtrace for how that happens:</p>

<pre><code>#4  0x000000000040549a in __interface_set_up (iface=0x6339c0) at /home/philipc/pkg/netifd/interface.c:280
#5  0x000000000040c75c in device_broadcast_cb (ctx=0x55c9, list=0x0) at /home/philipc/pkg/netifd/device.c:287
#6  0x00007ffff7bd660e in safe_list_for_each (head=head@entry=0x633850, cb=cb@entry=0x40c741 <device_broadcast_cb>, 
    ctx=ctx@entry=0x7fffffffe43c) at /home/philipc/pkg/libubox/safe_list.c:74
#7  0x000000000040c845 in device_broadcast_event (dev=dev@entry=0x633810, ev=ev@entry=DEV_EVENT_UP)
    at /home/philipc/pkg/netifd/device.c:296
#8  0x000000000040c8f0 in device_claim (dep=dep@entry=0x633270) at /home/philipc/pkg/netifd/device.c:315
#9  0x0000000000405ff2 in interface_set_up (iface=0x6331b0) at /home/philipc/pkg/netifd/interface.c:1009
#10 0x0000000000406de9 in interface_start_pending () at /home/philipc/pkg/netifd/interface.c:1040
#11 0x000000000040c6d8 in config_init_all () at /home/philipc/pkg/netifd/config.c:432
</code></pre>

<p>I can workaround the problem with the following patch. This doesn't seem like the correct way to fix this properly though: should we be calling device_claim() somewhere instead?</p>

<pre><code>diff --git a/interface.c b/interface.c
index 848990e..b5a399d 100644
--- a/interface.c
+++ b/interface.c
@@ -275,6 +275,9 @@ __interface_set_up(struct interface *iface)
 {
    int ret;

+   if (iface->main_dev.dev && !iface->main_dev.claimed)
+       return -1;
+
    netifd_log_message(L_NOTICE, "Interface '%s' is setting up now\n", iface->name);

    iface->state = IFS_SETUP;
</code></pre>

<p style="font-size:small;color:#666">—<br>Reply to this email directly or <a href="https://github.com/openwrt/packages/issues/1476" target="_blank">view it on GitHub</a>.<img alt="" src="https://github.com/notifications/beacon/ACo3jHc9MzEAdg_mgNw8pCVViWGgHHv1ks5oXNqvgaJpZM4FMamE.gif" height="1" width="1"></p>
<div>
  <div>
    
    
  </div>
  
</div>
</div><br></div></div>