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

next in thread | raw e-mail | index | archive | help
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 m=
y
>> 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)
{
        struct mbuf *m;

        SOCKBUF_LOCK_ASSERT(sb);

        if (m0 =3D=3D 0)
                return;
        m =3D sb->sb_mb;

        if (m)
                while (m->m_nextpkt)
                        m =3D m->m_nextpkt;

--> m is still NULL at this point

        /*
         * Put the first mbuf on the queue.  Note this permits zero length
         * records.
         */
        sballoc(sb, m0);
        SBLASTRECORDCHK(sb);

--> passed successfully, because sb_mb =3D=3D sb_lastrecord =3D=3D NULL (i.=
e.
sockbuf is empty)

        SBLINKRECORD(sb, m0);

--> at this point sb_mb =3D=3D sb_lastrecord  =3D=3D m0, _but_ sb_mtail =3D=
=3D NULL

        if (m)
                m->m_nextpkt =3D m0;
        else
                sb->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

        m =3D m0->m_next;
        m0->m_next =3D 0;

--> m is still NULL here

        if (m && (m0->m_flags & M_EOR)) {
                m0->m_flags &=3D ~M_EOR;
                m->m_flags |=3D M_EOR;
        }

--> sbcompress() is called with m =3D=3D NULL, which is triggers the panic
(read below)

        sbcompress(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)
{
        int eor =3D 0;
        struct mbuf *o;

        SOCKBUF_LOCK_ASSERT(sb);

        while (m) {

--> lots of code that never gets executed because m =3D=3D NULL

        }
        if (eor) {
                KASSERT(n !=3D NULL, ("sbcompress: eor && n =3D=3D NULL"));
                n->m_flags |=3D eor;
        }

--> this where panic happens, because sb_mbtail is still NULL, but
sockbuf now contains exactly one record

        SBLASTMBUFCHK(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.

comments anyone?

thanks,
max



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