diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2010-07-15 09:45:10 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2010-07-15 09:45:10 +0000 |
commit | 20b7e678b3cd86a686e69a3040bc4d0cacd50b12 (patch) | |
tree | a86464cd95368d467754d5a1adc9b6afb4b9af89 /sys/kern | |
parent | 959cd66e59fe388f6811a5f72f0d6335fe4310d1 (diff) |
m_getptr(m, 0, ...) may return an mbuf different from m -- if m has no
data in it. m_getptr() hops over empty buffers and points to the first
allocated data byte. Because of this the m_dup_pkthdr() call done by
m_copym0() can panic because not the first mbuf is passed.
Found the hard way by myself, diff by blambert@ commiitting for him since
he is not around. Tested and OK myself
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/uipc_mbuf.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 1b6400ce022..a823ea6cef6 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_mbuf.c,v 1.142 2010/07/14 10:31:54 matthew Exp $ */ +/* $OpenBSD: uipc_mbuf.c,v 1.143 2010/07/15 09:45:09 claudio Exp $ */ /* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */ /* @@ -620,17 +620,17 @@ m_copym2(struct mbuf *m, int off, int len, int wait) } struct mbuf * -m_copym0(struct mbuf *m, int off, int len, int wait, int deep) +m_copym0(struct mbuf *m0, int off, int len, int wait, int deep) { - struct mbuf *n, **np; + struct mbuf *m, *n, **np; struct mbuf *top; int copyhdr = 0; if (off < 0 || len < 0) panic("m_copym0: off %d, len %d", off, len); - if (off == 0 && m->m_flags & M_PKTHDR) + if (off == 0 && m0->m_flags & M_PKTHDR) copyhdr = 1; - if ((m = m_getptr(m, off, &off)) == NULL) + if ((m = m_getptr(m0, off, &off)) == NULL) panic("m_copym0: short mbuf chain"); np = ⊤ top = NULL; @@ -645,7 +645,7 @@ m_copym0(struct mbuf *m, int off, int len, int wait, int deep) if (n == NULL) goto nospace; if (copyhdr) { - if (m_dup_pkthdr(n, m)) + if (m_dup_pkthdr(n, m0)) goto nospace; if (len != M_COPYALL) n->m_pkthdr.len = len; |