summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/uipc_sockbuf.c9
-rw-r--r--sys/kern/uipc_socket2.c9
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);
}