On Tue, Dec 06, 2022 at 11:33:06PM +0300, Vitaliy Makkoveev wrote:
> On Tue, Dec 06, 2022 at 07:56:13PM +0100, Paul de Weerd wrote:
> > I was playing with the USB NIC that's in my (USB-C) monitor.  As soon
> > as I do traffic over the interface, I get a kernel panic:
> > 
> > panic: kernel diagnostic assertion "timo || _kernel_lock_held()" failed: 
> > file "/usr/src/sys/kern/kern_synch.c", line 127
> > 
> 
> I missed, in{,6}_addmulti() have no kernel lock around (*if_ioctl)().
> But corresponding in{,6}_delmulti() have.

OK bluhm@

> Index: sys/netinet/in.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/in.c,v
> retrieving revision 1.178
> diff -u -p -r1.178 in.c
> --- sys/netinet/in.c  19 Nov 2022 14:26:40 -0000      1.178
> +++ sys/netinet/in.c  6 Dec 2022 19:47:12 -0000
> @@ -885,10 +885,13 @@ in_addmulti(struct in_addr *ap, struct i
>                */
>               memset(&ifr, 0, sizeof(ifr));
>               memcpy(&ifr.ifr_addr, &inm->inm_sin, sizeof(inm->inm_sin));
> +             KERNEL_LOCK();
>               if ((*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
> +                     KERNEL_UNLOCK();
>                       free(inm, M_IPMADDR, sizeof(*inm));
>                       return (NULL);
>               }
> +             KERNEL_UNLOCK();
>  
>               TAILQ_INSERT_HEAD(&ifp->if_maddrlist, &inm->inm_ifma,
>                   ifma_list);
> Index: sys/netinet6/in6.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/in6.c,v
> retrieving revision 1.258
> diff -u -p -r1.258 in6.c
> --- sys/netinet6/in6.c        2 Dec 2022 12:56:51 -0000       1.258
> +++ sys/netinet6/in6.c        6 Dec 2022 19:47:12 -0000
> @@ -1063,7 +1063,9 @@ in6_addmulti(struct in6_addr *maddr6, st
>                * filter appropriately for the new address.
>                */
>               memcpy(&ifr.ifr_addr, &in6m->in6m_sin, sizeof(in6m->in6m_sin));
> +             KERNEL_LOCK();
>               *errorp = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, (caddr_t)&ifr);
> +             KERNEL_UNLOCK();
>               if (*errorp) {
>                       free(in6m, M_IPMADDR, sizeof(*in6m));
>                       return (NULL);

Reply via email to