Martin Pieuchot <m...@openbsd.org> writes:

> Last change reworking art_walk() introduced a regression leading to a
> of-by-one in rtable_walk().  You can trigger it by running the route(8)
> regress test 5:
>
> # cd /usr/src/regress/sbin/route && make rttest 5
> # route -T5 -n show
> Routing tables
>
> Internet:
> Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface
> 10.8.1/24          192.0.2.2          UGS        0        0 32768    18 (null)
> 10.8.1/24          192.0.2.2          GS         0        1 32768    16 (null)
>
> See the two dangling pointers?
>
> Problem is that rtable_walk_helper() have to keep a reference to the next
> entry in the multipath chain otherwise we might forget it when purging all
> the items.  Here it should be to use the _LOCKED() variant since the helper
> will be called inside art_walk() which will grab the mutex.
>
> Diff below also correct the KASSERT() when deleting an entry.  The refcount
> *must* be at least 2 at this point: 1 for being in the table and 1 for the
> caller.  This should be committed separately.
>
> Comments, ok?

I'm hitting a crash when net/iodine closes its tun device.  Your diff
fixes it.

$ ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 32768
        index 4 priority 0 llprio 3
        groups: lo
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4
        inet 127.0.0.1 netmask 0xff000000
iwn0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:21:6a:xx:xx:xx
        index 1 priority 4 llprio 3
        groups: wlan egress
        media: IEEE802.11 autoselect (DS1 mode 11g)
        status: active
        ieee80211: nwid "SFR WiFi FON" chan 1 bssid 7a:17:33:e9:da:e5 -91dBm
        inet 192.168.2.71 netmask 0xffffff00 broadcast 192.168.2.255
msk0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:24:54:xx:xx:xx
        index 2 priority 0 llprio 3
        media: Ethernet autoselect (none)
        status: no carrier
enc0: flags=0<>
        index 3 priority 0 llprio 3
        groups: enc
        status: active
pflog0: flags=141<UP,RUNNING,PROMISC> mtu 33188
        index 5 priority 0 llprio 3
        groups: pflog
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1130
        index 6 priority 0 llprio 3
        groups: tun
        status: active
        inet 192.168.97.2 --> 192.168.97.2 netmask 0xffffffe0

$ route -n show -inet
Routing tables

Internet:
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface
default            192.168.2.1        UGS        1       74     -    12 iwn0 
224/4              127.0.0.1          URS        0        0 32768     8 lo0  
127/8              127.0.0.1          UGRS       0        0 32768     8 lo0  
127.0.0.1          127.0.0.1          UHl        1       13 32768     1 lo0  
192.168.2/24       192.168.2.71       UC         1        0     -     4 iwn0 
192.168.2.1        7a:17:33:e9:da:e5  UHLc       1        2     -     4 iwn0 
192.168.2.71       00:21:6a:60:d0:e2  UHLl       0       58     -     1 iwn0 
192.168.2.255      192.168.2.71       UHb        0        0     -     1 iwn0 
192.168.97.0/27    192.168.97.2       UGS        0        1     -     8 tun0 
192.168.97.2       192.168.97.2       UHl        1        3     -     1 tun0 
192.168.97.2       192.168.97.2       UH         0        0     -     8 tun0 

/bsd: uvm_fault(0xd68825bc, 0x65567000, 0, 1) -> e
/bsd: kernel: page fault trap, code=0
/bsd: Stopped at        rt_if_remove_rtdelete+0xd:      movl    
clean_idt+0x1c(%edx),%eax

ddb shows iodine as curproc, quick and dirty ddb backtrace:

rt_if_remove_rtdelete
rtable_walk_helper
art_table_walk
art_table_walk
art_table_walk
art_table_walk
art_table_walk
art_table_walk
art_walk
rtable_walk
rt_if_remove
if_detach
tun_clone_destroy
spec_close
...
sys_close
syscall

Let me know if you need more details.

-- 
jca | PGP: 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to