summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_sockbuf.c
diff options
context:
space:
mode:
authoremax <emax@FreeBSD.org>2009-04-21 19:14:13 +0000
committeremax <emax@FreeBSD.org>2009-04-21 19:14:13 +0000
commit08708b99cb0019857302bee2d0c9290bb75800c2 (patch)
tree2f52463e7bbca063cdf76165863a3d3eb3a64eba /sys/kern/uipc_sockbuf.c
parent72b01124b7c13e20360c6a772667b8d7fd551556 (diff)
downloadFreeBSD-src-08708b99cb0019857302bee2d0c9290bb75800c2.zip
FreeBSD-src-08708b99cb0019857302bee2d0c9290bb75800c2.tar.gz
Fix sbappendrecord_locked().
The main problem is that sbappendrecord_locked() relies on sbcompress() to set sb_mbtail. This will not happen if sbappendrecord_locked() is called with mbuf chain made of exactly one mbuf (i.e. m0->m_next == NULL). In this case sbcompress() will be called with m == NULL and will do nothing. I'm not entirely sure if m == NULL is a valid argument for sbcompress(), and, it rather pointless to call it like that, but keep calling it so it can do SBLASTMBUFCHK(). The problem is triggered by the SOCKBUF_DEBUG kernel option that enables SBLASTRECORDCHK() and SBLASTMBUFCHK() checks. PR: kern/126742 Investigated by: pluknet < pluknet -at- gmail -dot- com > No response from: freebsd-current@, freebsd-bluetooth@ MFC after: 3 days
Diffstat (limited to 'sys/kern/uipc_sockbuf.c')
-rw-r--r--sys/kern/uipc_sockbuf.c10
1 files changed, 2 insertions, 8 deletions
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index ab5d150..8c0a618 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -577,10 +577,6 @@ sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0)
if (m0 == 0)
return;
- m = sb->sb_mb;
- if (m)
- while (m->m_nextpkt)
- m = m->m_nextpkt;
/*
* Put the first mbuf on the queue. Note this permits zero length
* records.
@@ -588,16 +584,14 @@ sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0)
sballoc(sb, m0);
SBLASTRECORDCHK(sb);
SBLINKRECORD(sb, m0);
- if (m)
- m->m_nextpkt = m0;
- else
- sb->sb_mb = m0;
+ sb->sb_mbtail = m0;
m = m0->m_next;
m0->m_next = 0;
if (m && (m0->m_flags & M_EOR)) {
m0->m_flags &= ~M_EOR;
m->m_flags |= M_EOR;
}
+ /* always call sbcompress() so it can do SBLASTMBUFCHK() */
sbcompress(sb, m, m0);
}
OpenPOWER on IntegriCloud