On Mon, Oct 27, 2025 at 08:54:02PM +0300, Vitaliy Makkoveev wrote:
> Seems the whole sppp_output() should take kernel lock. I have no ability
> to test this diff.

I also came to the conclusion that some big kernel lock is missing.
Just wondering why this bug appears now.  We have removed kernel
lock from network stack a long time ago.

OK bluhm@

> Index: sys/net/if_spppsubr.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_spppsubr.c,v
> retrieving revision 1.198
> diff -u -p -r1.198 if_spppsubr.c
> --- sys/net/if_spppsubr.c     19 Aug 2025 12:34:15 -0000      1.198
> +++ sys/net/if_spppsubr.c     27 Oct 2025 17:51:15 -0000
> @@ -591,6 +591,7 @@ sppp_output(struct ifnet *ifp, struct mb
>       }
>  #endif
>  
> +     KERNEL_LOCK();
>       s = splnet();
>  
>       getmicrouptime(&tv);
> @@ -599,8 +600,8 @@ sppp_output(struct ifnet *ifp, struct mb
>       if ((ifp->if_flags & IFF_UP) == 0 ||
>           (ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == 0) {
>               m_freem (m);
> -             splx (s);
> -             return (ENETDOWN);
> +             rv = ENETDOWN;
> +             goto out;
>       }
>  
>       if ((ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == IFF_AUTO) {
> @@ -635,11 +636,9 @@ sppp_output(struct ifnet *ifp, struct mb
>                       u_int8_t proto = ip->ip_p;
>  
>                       m_freem(m);
> -                     splx(s);
>                       if (proto == IPPROTO_TCP)
> -                             return (EADDRNOTAVAIL);
> -                     else
> -                             return (0);
> +                             rv = EADDRNOTAVAIL;
> +                     goto out;
>               }
>       }
>  
> @@ -677,8 +676,8 @@ sppp_output(struct ifnet *ifp, struct mb
>       default:
>               m_freem(m);
>               ++ifp->if_oerrors;
> -             splx(s);
> -             return (EAFNOSUPPORT);
> +             rv = EAFNOSUPPORT;
> +             goto out;
>       }
>  
>       M_PREPEND(m, 2, M_DONTWAIT);
> @@ -688,8 +687,9 @@ sppp_output(struct ifnet *ifp, struct mb
>                           "no memory for transmit header\n",
>                           SPP_ARGS(ifp));
>               ++ifp->if_oerrors;
> -             splx(s);
> -             return (rv ? rv : ENOBUFS);
> +             if (rv == 0)
> +                     rv = ENOBUFS;
> +             goto out;
>       }
>       *mtod(m, u_int16_t *) = protocol;
>  
> @@ -700,8 +700,7 @@ sppp_output(struct ifnet *ifp, struct mb
>       rv = if_enqueue(ifp, m);
>       if (rv != 0) {
>               ifp->if_oerrors++;
> -             splx(s);
> -             return (rv);
> +             goto out;
>       }
>  
>       /*
> @@ -710,9 +709,10 @@ sppp_output(struct ifnet *ifp, struct mb
>        * according to RFC 1333.
>        */
>       ifp->if_obytes += sp->pp_framebytes;
> +out:
> +     KERNEL_UNLOCK();
>       splx(s);
> -
> -     return (0);
> +     return (rv);
>  }
>  
>  void

Reply via email to