On 2022-07-12 14:35 +02, Florian Obser <flor...@openbsd.org> wrote:
> When the autoconf flag flaps around we might end up with multiple bpf
> FDs in flight. Things then get confusing. The kernel tells us we can
> read from the bpf FD but the data is actually "on the other FD", so
> read(2) returns 0.
>
> Found the hard way by, and patiently debugged with weerd@
>
> One way to trigger this is booting a vmm VM where dhcpleased(8)'s
> init_ifaces() loses a race against netstart(8). init_ifaces() would
> already see the autoconf flag and request a bpf FD.
> But then it would receive a RTM_IFINFO message without the autoconf flag
> set from when the interface came up. Then it will see another RTM_IFINFO
> message with the autoconf flag set and request yet another bpf FD. If
> the first bpf FD had not arrived yet we ended up with two in the frontend
> process.
>
> While here make sure a bpf FD has been configured before calling
> close(2) on it.
>
> OK?
>

Anyone? This is a slightly annoying bug... Difficult to hit though.


diff --git frontend.c frontend.c
index 2959a6c0d0f..275e5352e0b 100644
--- frontend.c
+++ frontend.c
@@ -1170,8 +1170,10 @@ remove_iface(uint32_t if_index)
                return;
 
        LIST_REMOVE(iface, entries);
-       event_del(&iface->bpfev.ev);
-       close(EVENT_FD(&iface->bpfev.ev));
+       if (event_initialized(&iface->bpfev.ev)) {
+               event_del(&iface->bpfev.ev);
+               close(EVENT_FD(&iface->bpfev.ev));
+       }
        if (iface->udpsock != -1)
                close(iface->udpsock);
        free(iface);
@@ -1185,7 +1187,13 @@ set_bpfsock(int bpfsock, uint32_t if_index)
        if ((iface = get_iface_by_id(if_index)) == NULL) {
                /*
                 * The interface disappeared while we were waiting for the
-                * parent process to open the raw socket.
+                * parent process to open the bpf socket.
+                */
+               close(bpfsock);
+       } else if (event_initialized(&iface->bpfev.ev)) {
+               /*
+                * The autoconf flag is flapping and we have multiple bpf 
sockets in
+                * flight. We don't need this one because we already got one.
                 */
                close(bpfsock);
        } else {


-- 
I'm not entirely sure you are real.

Reply via email to