Martin Pieuchot <[email protected]> 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