On Mon, Oct 27, 2025 at 02:55:56PM +0100, [email protected] wrote:
> Dear BSD-Team,
> 
> please find my bug-report about a problem with the pppoe-interface.
> 
> My hardware is a small appliance with 6 network interfaces, igc0 to igc5,
> where igc0 goes to LAN and igc1 goes to the modem, but it is not necessary
> to have one. The bug occured as well with an empty igc1 interface.
> 
> To reproduce the bug, please create the following files on a new installed
> OpenSD 7.8 system ...
> 
> /etc/hostname.igc1
> ---- Snip 8< ----
> inet 192.168.250.102 255.255.255.0
> up mtu 1500
> ---- Snap 8< ----
> 
> /etc/hostname.vlan7
> ---- Snip 8< ----
> vnetid 7 parent igc1
> up
> ---- Snap 8< ----
> 
> /etc/hostname.pppoe0
> ---- Snip 8< ----
> inet 0.0.0.0 255.255.255.255 NONE mtu 1492 \
>   pppoedev vlan7 authproto pap link1 \
>   authname 'testcaller' authkey 'donttell' up
> dest 0.0.0.1
> !/sbin/route add default -ifp pppoe0 0.0.0.1
> ---- Snap 8< ----
> 
> ... and reboot.
> 
> The bug occured on a different hardware, too and as well on OpenBSD 7.7.
> 
> The same configuration works fine from OpenBSD 5.x (or 6.x) up to OpenBSD
> 7.6.
> 
> If you have further questions, please let me know.
> 
> Kind regards,
> Illya Meyer

> >> OpenBSD/amd64 BOOTX64 3.69                                                 
> >>   
> switching console to com0                                                     
>   
>                                                                               
>   
> pf enabled                                                                    
>   
> starting network                                                              
>   
> add net default: gateway 0.0.0.1                                              
>   
> reordering: ld.so libc libcrypto sshd sshd-session sshd-auth ssh-agent.       
>   
> starting early daemons: syslogd pflogd ntpdpanic: kernel diagnostic assertion 
> "_
> kernel_lock_held()" failed: file "/usr/src                                    
>   
> /sys/net/if_pppoe.c", line 222                                                
>   
> Stopped at      db_enter+0x14:  popq    %rbp                                  
>   
>     TID    PID    UID     PRFLAGS     PFLAGS  CPU  COMMAND                    
>   
> *128183  69122     83   0x1100013          0    0  ntpd                       
>   
>  492573  68085      0     0x14000      0x200    2  softnet0                   
>   
> db_enter() at db_enter+0x14                                                   
>   
> panic(ffffffff825f1d7f) at panic+0xd5                                         
>   
> __assert(ffffffff8262d946,ffffffff8267c399,de,ffffffff8267bf7e) at 
> __assert+0x2 
> 9                                                                             
>   
> pppoe_tls(ffff8000004a7000) at pppoe_tls+0x13c                                
>   
> sppp_output(ffff8000004a7000,fffffd803e90f500,ffff800001393960,fffffd82709bb5d8
>  
> ) at sppp_output+0x187                                                        
>   
> if_output_tso(ffff8000004a7000,ffff8000360e6590,ffff800001393960,fffffd82709bb5
>  
> d8,5d4) at if_output_tso+0xf6                                                 
>   
> ip_output(fffffd803e90f500,0,fffffd8271bf7820,800,0,fffffd8271bf78b8,98eb194f7a
>  
> d82df2) at ip_output+0x7ee                                                    
>   
> tcp_output(ffff800001e5d9e0) at tcp_output+0x1a53                             
>   
> tcp_connect(ffff8000015668a8,fffffd803e90f100) at tcp_connect+0x28c           
>   
> sys_connect(ffff800035fbd250,ffff8000360e6930,ffff8000360e68b0) at 
> sys_connect+ 
> 0x1c0                                                                         
>   
> syscall(ffff8000360e6930) at syscall+0x5f9                                    
>   
> Xsyscall() at Xsyscall+0x128                                                  
>   
> end of kernel                                                                 
>   
Seems the whole sppp_output() should take kernel lock. I have no ability
to test this diff.

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