From 23f84772ca592a4134295603d78fb169f53b510b Mon Sep 17 00:00:00 2001 From: Pierre Beyssac Date: Tue, 28 Sep 1999 12:59:18 +0000 Subject: [PATCH] In sbflush(), don't exit the while loop too early: this can cause an empty mbuf to stay in the queue, then causing a needless panic because sb_cc == 0 and sb_mbcnt != 0. But we still need to panic rather than endlessly looping if, for some reason, sb_cc == 0 and there are non-empty mbufs in the queue. PR: kern/11988 Reviewed by: fenner --- sys/kern/uipc_sockbuf.c | 9 ++++++++- sys/kern/uipc_socket2.c | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index a51f98379cd6..9c1cd07eb2d5 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -730,8 +730,15 @@ sbflush(sb) if (sb->sb_flags & SB_LOCK) panic("sbflush: locked"); - while (sb->sb_mbcnt && sb->sb_cc) + while (sb->sb_mbcnt) { + /* + * Don't call sbdrop(sb, 0) if the leading mbuf is non-empty: + * we would loop forever. Panic instead. + */ + if (!sb->sb_cc && (sb->sb_mb == NULL || sb->sb_mb->m_len)) + break; sbdrop(sb, (int)sb->sb_cc); + } 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 a51f98379cd6..9c1cd07eb2d5 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -730,8 +730,15 @@ sbflush(sb) if (sb->sb_flags & SB_LOCK) panic("sbflush: locked"); - while (sb->sb_mbcnt && sb->sb_cc) + while (sb->sb_mbcnt) { + /* + * Don't call sbdrop(sb, 0) if the leading mbuf is non-empty: + * we would loop forever. Panic instead. + */ + if (!sb->sb_cc && (sb->sb_mb == NULL || sb->sb_mb->m_len)) + break; sbdrop(sb, (int)sb->sb_cc); + } 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); }