aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2009-06-24 05:28:09 +0000
committerColin Percival <cperciva@FreeBSD.org>2009-06-24 05:28:09 +0000
commit90c934b8926926502eca5d72b3f66a9ad00e38d9 (patch)
tree81077ca78a08a7c06628f1aa37dfee5f12d939a7
parent1baa48a657c12243a988556dba78f381710cf60f (diff)
downloadsrc-90c934b8926926502eca5d72b3f66a9ad00e38d9.tar.gz
src-90c934b8926926502eca5d72b3f66a9ad00e38d9.zip
MFS r192477: Fix packet length calculation in bce(4). [EN-09:02]
MFS r191867: Correctly set IP packet length for TSO in fxp(4). [EN-09:03] MFS r191767: Fix a lock order reversal bug that could cause deadlock during fork(2). [EN-09:04] Submitted by: re (kensmith) Approved by: so (cperciva) Errata: FreeBSD-SA-09:02.bce Errata: FreeBSD-SA-09:03.fxp Errata: FreeBSD-SA-09:04.fork
Notes
Notes: svn path=/releng/7.2/; revision=194808
-rw-r--r--UPDATING9
-rw-r--r--lib/libc/stdlib/malloc.c48
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--sys/dev/bce/if_bce.c3
-rw-r--r--sys/dev/fxp/if_fxp.c3
5 files changed, 52 insertions, 13 deletions
diff --git a/UPDATING b/UPDATING
index 3b4c08ae605c..6a921b2011b1 100644
--- a/UPDATING
+++ b/UPDATING
@@ -8,6 +8,15 @@ Items affecting the ports and packages system can be found in
/usr/ports/UPDATING. Please read that file before running
portupgrade.
+20090624: p2 FreeBSD-EN-09:02.bce, FreeBSD-EN-09:03.fxp,
+ FreeBSD-EN-09:04.fork
+ Fix packet length calculation in bce(4). [EN-09:02]
+
+ Correctly set IP packet length for TSO in fxp(4). [EN-09:03]
+
+ Fix a lock order reversal bug that could cause deadlock during
+ fork(2). [EN-09:04]
+
20090610: p1 FreeBSD-SA-09:09.pipe, FreeBSD-SA-09:10.ipv6,
FreeBSD-SA-09:11.ntpd
Prevent integer overflow in direct pipe write code from circumventing
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
index c07e38bdec4a..9328c27f0503 100644
--- a/lib/libc/stdlib/malloc.c
+++ b/lib/libc/stdlib/malloc.c
@@ -4715,16 +4715,41 @@ _malloc_thread_cleanup(void)
void
_malloc_prefork(void)
{
- unsigned i;
+ bool again;
+ unsigned i, j;
+ arena_t *larenas[narenas], *tarenas[narenas];
/* Acquire all mutexes in a safe order. */
- malloc_spin_lock(&arenas_lock);
- for (i = 0; i < narenas; i++) {
- if (arenas[i] != NULL)
- malloc_spin_lock(&arenas[i]->lock);
- }
- malloc_spin_unlock(&arenas_lock);
+ /*
+ * arenas_lock must be acquired after all of the arena mutexes, in
+ * order to avoid potential deadlock with arena_lock_balance[_hard]().
+ * Since arenas_lock protects the arenas array, the following code has
+ * to race with arenas_extend() callers until it succeeds in locking
+ * all arenas before locking arenas_lock.
+ */
+ memset(larenas, 0, sizeof(arena_t *) * narenas);
+ do {
+ again = false;
+
+ malloc_spin_lock(&arenas_lock);
+ for (i = 0; i < narenas; i++) {
+ if (arenas[i] != larenas[i]) {
+ memcpy(tarenas, arenas, sizeof(arena_t *) *
+ narenas);
+ malloc_spin_unlock(&arenas_lock);
+ for (j = 0; j < narenas; j++) {
+ if (larenas[j] != tarenas[j]) {
+ larenas[j] = tarenas[j];
+ malloc_spin_lock(
+ &larenas[j]->lock);
+ }
+ }
+ again = true;
+ break;
+ }
+ }
+ } while (again);
malloc_mutex_lock(&base_mtx);
@@ -4739,6 +4764,7 @@ void
_malloc_postfork(void)
{
unsigned i;
+ arena_t *larenas[narenas];
/* Release all mutexes, now that fork() has completed. */
@@ -4750,12 +4776,12 @@ _malloc_postfork(void)
malloc_mutex_unlock(&base_mtx);
- malloc_spin_lock(&arenas_lock);
+ memcpy(larenas, arenas, sizeof(arena_t *) * narenas);
+ malloc_spin_unlock(&arenas_lock);
for (i = 0; i < narenas; i++) {
- if (arenas[i] != NULL)
- malloc_spin_unlock(&arenas[i]->lock);
+ if (larenas[i] != NULL)
+ malloc_spin_unlock(&larenas[i]->lock);
}
- malloc_spin_unlock(&arenas_lock);
}
/*
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 76848bf386f0..22ebb11ee348 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
TYPE="FreeBSD"
REVISION="7.2"
-BRANCH="RELEASE-p1"
+BRANCH="RELEASE-p2"
if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
BRANCH=${BRANCH_OVERRIDE}
fi
diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
index 7c772e13b5a1..c725611c55e4 100644
--- a/sys/dev/bce/if_bce.c
+++ b/sys/dev/bce/if_bce.c
@@ -5895,6 +5895,9 @@ bce_rx_intr(struct bce_softc *sc)
/* Set the total packet length. */
m0->m_pkthdr.len = m0->m_len = pkt_len;
}
+#else
+ /* Set the total packet length. */
+ m0->m_pkthdr.len = m0->m_len = pkt_len;
#endif
/* Remove the trailing Ethernet FCS. */
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index ca1a6141ae3f..39c36a87bde8 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -1486,7 +1486,8 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
* checksum in the first frame driver should compute it.
*/
ip->ip_sum = 0;
- ip->ip_len = htons(ifp->if_mtu);
+ ip->ip_len = htons(m->m_pkthdr.tso_segsz + (ip->ip_hl << 2) +
+ (tcp->th_off << 2));
tcp->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
htons(IPPROTO_TCP + (tcp->th_off << 2) +
m->m_pkthdr.tso_segsz));