tech-net archive

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

infinite recursion in m_split()



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).

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 ?

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: uipc_mbuf.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.128
diff -u -r1.128 uipc_mbuf.c
--- uipc_mbuf.c 2 Jul 2008 14:47:34 -0000       1.128
+++ uipc_mbuf.c 2 Apr 2009 20:26:04 -0000
@@ -1019,11 +1019,12 @@
 struct mbuf *
 m_split(struct mbuf *m0, int len0, int wait)
 {
-
+       if (len0 == 0)
+               return (m0);
        return m_split0(m0, len0, wait, 1);
 }
 
 static struct mbuf *
 m_split0(struct mbuf *m0, int len0, int wait, int copyhdr)
 {
        struct mbuf *m, *n;


Home | Main Index | Thread Index | Old Index