From 0931333f8dd6c9dad30bdd34bc24901ebb914c41 Mon Sep 17 00:00:00 2001 From: Bill Fenner Date: Wed, 4 Nov 1998 20:22:11 +0000 Subject: [PATCH] Fix sbcheck() to check all packets on socket buffer. Also fix data types and printf formats while I'm here. PR: misc/8494 Panic instead of looping forever in sbflush(). If sb_mbcnt counts more mbufs than sb_cc counts bytes, the original code can turn into an infinite loop of removing 0 bytes from the socket buffer until it's empty. --- sys/kern/uipc_sockbuf.c | 20 +++++++++++--------- sys/kern/uipc_socket2.c | 20 +++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index a7405d97a191..23c7751776e7 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93 - * $Id: uipc_socket2.c,v 1.38 1998/09/04 13:13:18 ache Exp $ + * $Id: uipc_socket2.c,v 1.39 1998/09/05 13:24:39 bde Exp $ */ #include @@ -477,18 +477,20 @@ sbcheck(sb) register struct sockbuf *sb; { register struct mbuf *m; - register int len = 0, mbcnt = 0; + register struct mbuf *n = 0; + register u_long len = 0, mbcnt = 0; - for (m = sb->sb_mb; m; m = m->m_next) { + for (m = sb->sb_mb; m; m = n) { + n = m->m_nextpkt; + for (; m; m = m->m_next) { len += m->m_len; mbcnt += MSIZE; if (m->m_flags & M_EXT) /*XXX*/ /* pretty sure this is bogus */ mbcnt += m->m_ext.ext_size; - if (m->m_nextpkt) - panic("sbcheck nextpkt"); + } } if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) { - printf("cc %d != %d || mbcnt %d != %d\n", len, sb->sb_cc, + printf("cc %ld != %ld || mbcnt %ld != %ld\n", len, sb->sb_cc, mbcnt, sb->sb_mbcnt); panic("sbcheck"); } @@ -720,10 +722,10 @@ sbflush(sb) if (sb->sb_flags & SB_LOCK) panic("sbflush: locked"); - while (sb->sb_mbcnt) + while (sb->sb_mbcnt && sb->sb_cc) sbdrop(sb, (int)sb->sb_cc); - if (sb->sb_cc || sb->sb_mb) - panic("sbflush: cc %ld || mb %p", sb->sb_cc, (void *)sb->sb_mb); + if (sb->sb_cc || sb->sb_mb || sb->sb_mbcnt) + panic("sbflush: cc %ld || mb %p || mbcnt %ld", sb->sb_cc, (void *)sb->sb_mb, sb->sb_mbcnt); } /* diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index a7405d97a191..23c7751776e7 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93 - * $Id: uipc_socket2.c,v 1.38 1998/09/04 13:13:18 ache Exp $ + * $Id: uipc_socket2.c,v 1.39 1998/09/05 13:24:39 bde Exp $ */ #include @@ -477,18 +477,20 @@ sbcheck(sb) register struct sockbuf *sb; { register struct mbuf *m; - register int len = 0, mbcnt = 0; + register struct mbuf *n = 0; + register u_long len = 0, mbcnt = 0; - for (m = sb->sb_mb; m; m = m->m_next) { + for (m = sb->sb_mb; m; m = n) { + n = m->m_nextpkt; + for (; m; m = m->m_next) { len += m->m_len; mbcnt += MSIZE; if (m->m_flags & M_EXT) /*XXX*/ /* pretty sure this is bogus */ mbcnt += m->m_ext.ext_size; - if (m->m_nextpkt) - panic("sbcheck nextpkt"); + } } if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) { - printf("cc %d != %d || mbcnt %d != %d\n", len, sb->sb_cc, + printf("cc %ld != %ld || mbcnt %ld != %ld\n", len, sb->sb_cc, mbcnt, sb->sb_mbcnt); panic("sbcheck"); } @@ -720,10 +722,10 @@ sbflush(sb) if (sb->sb_flags & SB_LOCK) panic("sbflush: locked"); - while (sb->sb_mbcnt) + while (sb->sb_mbcnt && sb->sb_cc) sbdrop(sb, (int)sb->sb_cc); - if (sb->sb_cc || sb->sb_mb) - panic("sbflush: cc %ld || mb %p", sb->sb_cc, (void *)sb->sb_mb); + if (sb->sb_cc || sb->sb_mb || sb->sb_mbcnt) + panic("sbflush: cc %ld || mb %p || mbcnt %ld", sb->sb_cc, (void *)sb->sb_mb, sb->sb_mbcnt); } /*