summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarchie <archie@FreeBSD.org>2002-05-31 22:09:57 +0000
committerarchie <archie@FreeBSD.org>2002-05-31 22:09:57 +0000
commitf138a74bc88eb0aea934104e030bfa907243ba45 (patch)
tree13f7bcda0e57d982f4feaf39045da20fdf12bba1
parent43d66222dd584cbdfa479816200284385112943c (diff)
downloadFreeBSD-src-f138a74bc88eb0aea934104e030bfa907243ba45.zip
FreeBSD-src-f138a74bc88eb0aea934104e030bfa907243ba45.tar.gz
Fix a bug in m_split(): the "m->m_ext.ext_size" field of an mbuf was being
set to zero. This field indicates the total space in the external buffer and therefore should not be modified after the external buffer is added. Add a comment warning that the mbufs returned by m_split() might be read-only. Fix M_TRAILINGSPACE() to return zero if !M_WRITABLE(m). Reviewed by: freebsd-net Obtained from: Vernier Networks, Inc. MFC after: 1 week
-rw-r--r--sys/kern/uipc_mbuf.c6
-rw-r--r--sys/sys/mbuf.h11
2 files changed, 14 insertions, 3 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 80c4061..27ca156 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -560,6 +560,11 @@ bad:
* Partition an mbuf chain in two pieces, returning the tail --
* all but the first len0 bytes. In case of failure, it returns NULL and
* attempts to restore the chain to its original state.
+ *
+ * Note that the resulting mbufs might be read-only, because the new
+ * mbuf can end up sharing an mbuf cluster with the original mbuf if
+ * the "breaking point" happens to lie within a cluster mbuf. Use the
+ * M_WRITABLE() macro to check for this case.
*/
struct mbuf *
m_split(struct mbuf *m0, int len0, int wait)
@@ -609,7 +614,6 @@ extpacket:
n->m_flags |= M_EXT;
n->m_ext = m->m_ext;
MEXT_ADD_REF(m);
- m->m_ext.ext_size = 0; /* For Accounting XXXXXX danger */
n->m_data = m->m_data + len;
} else {
bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 4075a5d..5cfb1ae 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -344,6 +344,9 @@ struct mbstat {
/*
* Compute the amount of space available
* before the current start of data in an mbuf.
+ *
+ * The M_WRITABLE() is a temporary, conservative safety measure: the burden
+ * of checking writability of the mbuf data area rests solely with the caller.
*/
#define M_LEADINGSPACE(m) \
((m)->m_flags & M_EXT ? \
@@ -354,10 +357,14 @@ struct mbstat {
/*
* Compute the amount of space available
* after the end of data in an mbuf.
+ *
+ * The M_WRITABLE() is a temporary, conservative safety measure: the burden
+ * of checking writability of the mbuf data area rests solely with the caller.
*/
#define M_TRAILINGSPACE(m) \
- ((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + \
- (m)->m_ext.ext_size - ((m)->m_data + (m)->m_len) : \
+ ((m)->m_flags & M_EXT ? \
+ (M_WRITABLE(m) ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size \
+ - ((m)->m_data + (m)->m_len) : 0) : \
&(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
/*
OpenPOWER on IntegriCloud