tech-net archive

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

Re: infinite recursion in m_split()



On Fri, Apr 03, 2009 at 06:18:35PM +0200, Manuel Bouyer wrote:
> [...]
> already happened. The attached patch gives more details on how we get in
> this situation:
> m 0xc3bae000 m0 0xc3bae000 remain 1444 len_save -4 len0 0 len 0 m_len 1444 
> MHLEN 200
> panic: m_split0

Sorry forgot the patch, here it is

> 
> This mbuf obviously has a cluster attached (gdb on the core dump confirmed),
> yet it doesn't have M_EXT set (the (m->m_flags & M_EXT) goto didn't
> catch it, and gdb on the core dump also confirms). So the mbuf got partially
> updated before m_split() I also guess m0->m_pkthdr.len is not supposed
> to be negative, yet we have len_save as -4 (I've also seen -252 or -260).
> So something is putting wrong values in the mbuf before calling m_split()
> on it, but I don't know where it happens.
> The printf() I added to check for len0 == 0 at the top of m_split()
> fires only once, so I guess when slp->ns_reclen == 0 damage has already
> been done to the associated mbuf; it could be related to this
> specific condition.
> 
> Any idea very welcome.
> 
> -- 
> Manuel Bouyer, LIP6, Universite Paris VI.           
> Manuel.Bouyer%lip6.fr@localhost
>      NetBSD: 26 ans d'experience feront toujours la difference
> --
-- 
Manuel Bouyer, LIP6, Universite Paris VI.           
Manuel.Bouyer%lip6.fr@localhost
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: sys/kern/uipc_mbuf.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.128
diff -u -r1.128 uipc_mbuf.c
--- sys/kern/uipc_mbuf.c        2 Jul 2008 14:47:34 -0000       1.128
+++ sys/kern/uipc_mbuf.c        3 Apr 2009 16:16:47 -0000
@@ -108,7 +108,7 @@
 };
 
 static struct mbuf *m_copym0(struct mbuf *, int, int, int, int);
-static struct mbuf *m_split0(struct mbuf *, int, int, int);
+struct mbuf *m_split0(struct mbuf *, int, int, int);
 static int m_copyback0(struct mbuf **, int, int, const void *, int, int);
 
 /* flags for m_copyback0 */
@@ -1019,11 +1019,12 @@
 struct mbuf *
 m_split(struct mbuf *m0, int len0, int wait)
 {
-
+       if (len0 == 0) 
+               printf("m_split(%p, 0, %d)\n", m0, wait);
        return m_split0(m0, len0, wait, 1);
 }
 
-static struct mbuf *
+struct mbuf *
 m_split0(struct mbuf *m0, int len0, int wait, int copyhdr)
 {
        struct mbuf *m, *n;
@@ -1046,10 +1047,16 @@
                if (m->m_flags & M_EXT)
                        goto extpacket;
                if (remain > MHLEN) {
+                       if (m == m0) {
+                               printf ("m %p m0 %p remain %d len_save %d len0 
%d len %d m_len %d MHLEN %d\n", m, m0, remain, len_save, len0, len, m->m_len, 
MHLEN);
+                               panic("m_split0");
+                       }
                        /* m can't be the lead packet */
+                       KASSERT(m != m0);
+                       KASSERT((m->m_flags & M_PKTHDR) == 0);
                        MH_ALIGN(n, 0);
                        n->m_next = m_split(m, len, wait);
-                       if (n->m_next == 0) {
+                       if (n->m_next == NULL) {
                                (void) m_free(n);
                                m0->m_pkthdr.len = len_save;
                                return (NULL);
@@ -1059,11 +1066,11 @@
                        MH_ALIGN(n, remain);
        } else if (remain == 0) {
                n = m->m_next;
-               m->m_next = 0;
+               m->m_next = NULL;
                return (n);
        } else {
                MGET(n, wait, m->m_type);
-               if (n == 0)
+               if (n == NULL)
                        return (NULL);
                MCLAIM(n, m->m_owner);
                M_ALIGN(n, remain);
@@ -1078,7 +1085,7 @@
        n->m_len = remain;
        m->m_len = len;
        n->m_next = m->m_next;
-       m->m_next = 0;
+       m->m_next = NULL;
        return (n);
 }
 /*


Home | Main Index | Thread Index | Old Index