diff options
author | emax <emax@FreeBSD.org> | 2009-04-21 19:14:13 +0000 |
---|---|---|
committer | emax <emax@FreeBSD.org> | 2009-04-21 19:14:13 +0000 |
commit | 08708b99cb0019857302bee2d0c9290bb75800c2 (patch) | |
tree | 2f52463e7bbca063cdf76165863a3d3eb3a64eba /sys/kern/uipc_sockbuf.c | |
parent | 72b01124b7c13e20360c6a772667b8d7fd551556 (diff) | |
download | FreeBSD-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.c | 10 |
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); } |