On Mon, Apr 20, 2020 at 12:14:09PM +0200, Martin Pieuchot wrote:
> Thanks for the report.
>
> On 18/04/20(Sat) 18:17, Julian Brost wrote:
> > I encountered a reproducible kernel panic during an accidental IPv6
> > misconfiguration. In order to reproduce, the OpenBSD machine must be in
> > the same subnet as a router that has fe80::1/64 configured and sends
> > IPv6 route advertisements, for example with radvd using this config:
> >
> > interface eth0 {
> > AdvSendAdvert on;
> > MinRtrAdvInterval 10;
> > MaxRtrAdvInterval 30;
> > prefix 2001:db8::/64 {
> > AdvOnLink on;
> > AdvAutonomous on;
> > AdvRouterAddr on;
> > };
> > };
> >
> > With this setup, I was able to to reliably trigger the assertion using
> > the following steps:
> >
> > - Install Openbsd using 6.6/amd64 install66.iso
> > - IPv4: none
> > - IPv6: autoconf
> > - Reboot into system, log in
> > - echo inet6 alias fe80::1 64 >> /etc/hostname.vio0
> > # The file now contains the following:
> > # inet6 autoconf
> > # inet6 alias fe80::1 64
> > - Reboot and log in again
> > - ping6 2001::
> > # The exact address doesn't seem to matter, it also doesn't have to
> > # respond or anything. Sometimes this step isn't even necessary as the
> > # panic occurs by itself after the login prompt.
> > - Wait a bit (less than a minute in my case) and observe the panic
> >
> [...]
> > vio0: DAD detected duplicate IPv6 address fe80:1::1: NS in/out=0/1, NA in=1
> > vio0: DAD complete for fe80:1::1 - duplicate found
> > vio0: manual intervention required
>
> Interesting :)
>
> > login: panic: kernel diagnostic assertion "!ISSET(rt->rt_flags,
> > RTF_LOCAL)" failed: file "/usr/src/sys/netinet6/nd6.c", line 727
>
> That means some part of the ND code is incorrectly setting an `expire'
> value to an entry that is local, and therefor should never expire.
>
> Could you try to reproduce the issue with the diff below? It should
> also panic but points us to the place where the bug is.
>
> Index: netinet6/nd6.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/nd6.c,v
> retrieving revision 1.229
> diff -u -p -r1.229 nd6.c
> --- netinet6/nd6.c 29 Nov 2019 16:41:01 -0000 1.229
> +++ netinet6/nd6.c 20 Apr 2020 10:07:15 -0000
> @@ -306,6 +306,7 @@ nd6_llinfo_settimer(struct llinfo_nd6 *l
> time_t expire = time_uptime + secs;
>
> NET_ASSERT_LOCKED();
> + KASSERT(!ISSET(ln->ln_rt->rt_flags, RTF_LOCAL));
>
> ln->ln_rt->rt_expire = expire;
> if (!timeout_pending(&nd6_timer_to) || expire < nd6_timer_next) {
>
Also found by syzkaller.
https://syzkaller.appspot.com/bug?extid=0eb994ff432ae75e3369