On Sun, Dec 12, 2021 at 11:57:54PM +0100, Alexander Bluhm wrote:
> Hi,
>
> Syskaller has found a NULL deref in nd6_dad_duplicated().
>
> https://syzkaller.appspot.com/bug?id=f2ee1cc75911fa580176b09e7c1ab9d867590994
>
> The code in nd6_dad_ns_input() looks fishy. It checks dp in two
> of three places. One check got lost in revision 1.83. Do a dp ==
> NULL once at the beginning.
>
> ok?
ok jsg@
>
> bluhm
>
> Index: netinet6/nd6_nbr.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6_nbr.c,v
> retrieving revision 1.129
> diff -u -p -U6 -r1.129 nd6_nbr.c
> --- netinet6/nd6_nbr.c 29 Nov 2019 16:41:02 -0000 1.129
> +++ netinet6/nd6_nbr.c 12 Dec 2021 22:50:54 -0000
> @@ -1324,32 +1324,35 @@ nd6_dad_ns_input(struct ifaddr *ifa)
>
> if (!ifa)
> panic("%s: ifa == NULL", __func__);
>
> duplicate = 0;
> dp = nd6_dad_find(ifa);
> + if (dp == NULL) {
> + log(LOG_ERR, "%s: DAD structure not found\n", __func__);
> + return;
> + }
>
> /*
> * if I'm yet to start DAD, someone else started using this address
> * first. I have a duplicate and you win.
> */
> - if (!dp || dp->dad_ns_ocount == 0)
> + if (dp->dad_ns_ocount == 0)
> duplicate++;
>
> /* XXX more checks for loopback situation - see nd6_dad_timer too */
>
> if (duplicate) {
> /* dp will be freed in nd6_dad_duplicated() */
> nd6_dad_duplicated(dp);
> } else {
> /*
> * not sure if I got a duplicate.
> * increment ns count and see what happens.
> */
> - if (dp)
> - dp->dad_ns_icount++;
> + dp->dad_ns_icount++;
> }
> }
>
> /*
> * Check whether ``addr'' is a neighbor address connected to ``ifp''.
> */
>
>