tech-net archive

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

Re: infinite recursion in m_split()



hi,

> Hi,
> While debugging NFS server issues I found a infinite recursion in m_split
> when it's called with len0 == 0.
> it's called this way from nfsrv_getstream() (and this is even documented
> in the comment :):
>                 /*
>                  * Now get the record part.
>                  *
>                  * Note that slp->ns_reclen may be 0.  Linux sometimes
>                  * generates 0-length records.
>                  */
>                 if (slp->ns_cc == slp->ns_reclen) {
>                         recm = slp->ns_raw;
>                         slp->ns_raw = slp->ns_rawend = (struct mbuf *)0;
>                         slp->ns_cc = slp->ns_reclen = 0;
>                 } else if (slp->ns_cc > slp->ns_reclen) {
>                         recm = slp->ns_raw;
>                         m = m_split(recm, slp->ns_reclen, waitflag);
> 
> Then m_split() calls m_split0, which, if (m0->m_flags & M_PKTHDR)
> is true and (m->m_flags & M_EXT) is false, will call m_split() with
> the same mbuf and the same m0. This is an infinite loop (well, infinite
> until stack is exhausted).

good catch.

> Documentatio doesn't mention that calling m_split() with a 0 len0 is invalid.
> My fix is to check for (len0 == 0) in m_split() and return m0 in this case.
> Is it OK ?

the fix seems wrong because the caller of m_split will keep a reference to
the original m0 as well and it will be double-freed eventually.
i think it's more straightforward to fix nfsrv_getstream.

YAMAMOTO Takashi

> 
> -- 
> Manuel Bouyer <bouyer%antioche.eu.org@localhost>
>      NetBSD: 26 ans d'experience feront toujours la difference
> --


Home | Main Index | Thread Index | Old Index