Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Apr 2009 19:41:02 -0700
From:      Maksim Yevmenkin <maksim.yevmenkin@gmail.com>
To:        freebsd-current@freebsd.org
Cc:        Alexander Best <alexbestms@math.uni-muenster.de>
Subject:   Re: possible bug in the sbappendrecord_locked()? (Was: Re: core dump with bluetooth device)
Message-ID:  <bb4a86c70904161941v53cc0f90i8a1c94b1c0458e61@mail.gmail.com>
In-Reply-To: <bb4a86c70904161922t38819fd8r839e5e832aa1f1@mail.gmail.com>
References:  <bb4a86c70904161922t38819fd8r839e5e832aa1f1@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Apr 16, 2009 at 7:22 PM, Maksim Yevmenkin
<maksim.yevmenkin@gmail.com> wrote:
> On Thu, Apr 16, 2009 at 5:39 PM, Maksim Yevmenkin
> <maksim.yevmenkin@gmail.com> wrote:
>> On Thu, Apr 16, 2009 at 12:59 PM, Alexander Best
>> <alexbestms@math.uni-muenster.de> wrote:
>>> hi there,
>>>
>>> i'm running r191076M. when i try to send files from my mobile phone to =
my
>>> computer via bt the core dumps. here's a backtrace:
>>>
>>> Unread portion of the kernel message buffer:
>>> sblastmbufchk: sb_mb 0xc8d54d00 sb_mbtail 0 last 0xc8d54d00
>>> packet tree:
>>> =A0 =A0 =A0 =A00xc8d54d00
>>> panic: sblastmbufchk from /usr/src/sys/kern/uipc_sockbuf.c:797
>>> cpuid =3D 0
>>
>> are you, by change, have "options =A0SOCKBUF_DEBUG" in your kernel?
>
> ok, there is something strange going on in the
> sbappendrecord_locked(). consider the following initial conditions:
>
> 1) sockbuf sb is empty, i.e. sb_mb =3D=3D sb_mbtail =3D=3D sb_lastrecord =
=3D=3D NULL
>
> 2) sbappendrecord_locked() is given mbuf m0 with has exactly one mbuf,
> i.e. m0->m_next =3D=3D NULL
>
> so
>
> void
> sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0)
> {
> =A0 =A0 =A0 =A0struct mbuf *m;
>
> =A0 =A0 =A0 =A0SOCKBUF_LOCK_ASSERT(sb);
>
> =A0 =A0 =A0 =A0if (m0 =3D=3D 0)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return;
> =A0 =A0 =A0 =A0m =3D sb->sb_mb;
>
> =A0 =A0 =A0 =A0if (m)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0while (m->m_nextpkt)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0m =3D m->m_nextpkt;
>
> --> m is still NULL at this point
>
> =A0 =A0 =A0 =A0/*
> =A0 =A0 =A0 =A0 * Put the first mbuf on the queue. =A0Note this permits z=
ero length
> =A0 =A0 =A0 =A0 * records.
> =A0 =A0 =A0 =A0 */
> =A0 =A0 =A0 =A0sballoc(sb, m0);
> =A0 =A0 =A0 =A0SBLASTRECORDCHK(sb);
>
> --> passed successfully, because sb_mb =3D=3D sb_lastrecord =3D=3D NULL (=
i.e.
> sockbuf is empty)
>
> =A0 =A0 =A0 =A0SBLINKRECORD(sb, m0);
>
> --> at this point sb_mb =3D=3D sb_lastrecord =A0=3D=3D m0, _but_ sb_mtail=
 =3D=3D NULL
>
> =A0 =A0 =A0 =A0if (m)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0m->m_nextpkt =3D m0;
> =A0 =A0 =A0 =A0else
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0sb->sb_mb =3D m0;
>
> --> not sure about those lines above, didn't SBLINKRECORD(sb, m0) take
> care of it already?
> --> in any case, still, sb_mb =3D=3D sb_lastrecord =3D=3D m0 _and_ still
> sb_mtail =3D=3D NULL
>
> =A0 =A0 =A0 =A0m =3D m0->m_next;
> =A0 =A0 =A0 =A0m0->m_next =3D 0;
>
> --> m is still NULL here
>
> =A0 =A0 =A0 =A0if (m && (m0->m_flags & M_EOR)) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0m0->m_flags &=3D ~M_EOR;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0m->m_flags |=3D M_EOR;
> =A0 =A0 =A0 =A0}
>
> --> sbcompress() is called with m =3D=3D NULL, which is triggers the pani=
c
> (read below)
>
> =A0 =A0 =A0 =A0sbcompress(sb, m, m0);
> }
>
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>
> void
> sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n)
> {
> =A0 =A0 =A0 =A0int eor =3D 0;
> =A0 =A0 =A0 =A0struct mbuf *o;
>
> =A0 =A0 =A0 =A0SOCKBUF_LOCK_ASSERT(sb);
>
> =A0 =A0 =A0 =A0while (m) {
>
> --> lots of code that never gets executed because m =3D=3D NULL
>
> =A0 =A0 =A0 =A0}
> =A0 =A0 =A0 =A0if (eor) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0KASSERT(n !=3D NULL, ("sbcompress: eor && =
n =3D=3D NULL"));
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0n->m_flags |=3D eor;
> =A0 =A0 =A0 =A0}
>
> --> this where panic happens, because sb_mbtail is still NULL, but
> sockbuf now contains exactly one record
>
> =A0 =A0 =A0 =A0SBLASTMBUFCHK(sb);
> }
>
> so, it looks like, sbcompress() should only be called when m !=3D NULL.
> also, when m =3D=3D NULL, m0 should be marked as EOR.

actually, no, EOR should be set (or not set already).

> comments anyone?

i think there is also something strange going on in
sbappendaddr_locked(), basically,

int
sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
    struct mbuf *m0, struct mbuf *control)
{
        struct mbuf *m, *n, *nlast;
        int space =3D asa->sa_len;

        SOCKBUF_LOCK_ASSERT(sb);

        if (m0 && (m0->m_flags & M_PKTHDR) =3D=3D 0)
                panic("sbappendaddr_locked");
        if (m0)
                space +=3D m0->m_pkthdr.len;
        space +=3D m_length(control, &n);

        if (space > sbspace(sb))
                return (0);
#if MSIZE <=3D 256
        if (asa->sa_len > MLEN)
                return (0);
#endif
        MGET(m, M_DONTWAIT, MT_SONAME);
        if (m =3D=3D 0)
                return (0);
        m->m_len =3D asa->sa_len;
        bcopy(asa, mtod(m, caddr_t), asa->sa_len);

--> at this point n is not initialized, or at least i do not see where
it was initialized. shouldn't be compiler giving a warning here?

        if (n)
                n->m_next =3D m0;         /* concatenate data to control */
        else
                control =3D m0;

am i missing something obvious here?

thanks
max



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bb4a86c70904161941v53cc0f90i8a1c94b1c0458e61>