Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: panic using firefox



Kamil Rytarowski wrote:
>On 12.04.2016 14:14, Robert Swindells wrote:
>> Patrick Welche wrote:
>>> With a amd64 kernel built from Mar 28 16:05 GMT source, I just saw:
>> [snip]
>
>I just reproduced it.
>
>>> (gdb) frame 5
>>> #5  0xffffffff8054547a in filt_sordetach (kn=0xfffffe804e698780)
>>>    at ../../../../kern/uipc_socket.c:2250
>>> 2250            SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, kn_selnext);
>>> (gdb) list
>>> 2245    {
>>> 2246            struct socket   *so;
>>> 2247
>>> 2248            so = ((file_t *)kn->kn_obj)->f_socket;
>>> 2249            solock(so);
>>> 2250            SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, kn_selnext);
>>> 2251            if (SLIST_EMPTY(&so->so_rcv.sb_sel.sel_klist))
>>> 2252                    so->so_rcv.sb_flags &= ~SB_KNOTE;
>>> 2253            sounlock(so);
>>> 2254    }
>> I have seen the same crash twice with sources from Apr 11, I have
>> crash dumps but the kernel wasn't a debug build.
>>
>> Looking at the firefox sources the call to kevent(2) is presumably from:
>>
>> ipc/chromium/src/third_party/libevent/kqueue.c
>>
>> I guess it could be interesting to look at the fields of the socket
>> struct.

If close(2) has already been called on the socket before the call to
kevent(2) to delete the knote structure then f_socket would be NULL.

It also looks to me as if sofree() would leak any knote structures
that were attached.

I have put a bit of debug code in my local tree to test the theory.

Robert Swindells

Index: uipc_socket.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_socket.c,v
retrieving revision 1.247
diff -u -r1.247 uipc_socket.c
--- uipc_socket.c       13 Oct 2015 21:28:35 -0000      1.247
+++ uipc_socket.c       16 May 2016 21:47:56 -0000
@@ -709,6 +709,12 @@
        /* Remove acccept filter if one is present. */
        if (so->so_accf != NULL)
                (void)accept_filt_clear(so);
+       if (so->so_rcv.sb_flags & SB_KNOTE) {
+               printf("sofree: rcv knote\n");
+       }
+       if (so->so_snd.sb_flags & SB_KNOTE) {
+               printf("sofree: snd knote\n");
+       }
        sounlock(so);
        if (refs == 0)          /* XXX */
                soput(so);
@@ -2221,6 +2227,10 @@
        struct socket   *so;
 
        so = ((file_t *)kn->kn_obj)->f_socket;
+       if (so == NULL) {
+               printf("filt_sordetach: no socket\n");
+               return;
+       }
        solock(so);
        SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, kn_selnext);
        if (SLIST_EMPTY(&so->so_rcv.sb_sel.sel_klist))
@@ -2260,6 +2270,10 @@
        struct socket   *so;
 
        so = ((file_t *)kn->kn_obj)->f_socket;
+       if (so == NULL) {
+               printf("filt_sowdetach: no socket\n");
+               return;
+       }
        solock(so);
        SLIST_REMOVE(&so->so_snd.sb_sel.sel_klist, kn, knote, kn_selnext);
        if (SLIST_EMPTY(&so->so_snd.sb_sel.sel_klist))


Home | Main Index | Thread Index | Old Index