Path: blob/main/website/static/security/patches/EN-09:04/fork.patch
18096 views
Index: lib/libc/stdlib/malloc.c1===================================================================2RCS file: /home/ncvs/src/lib/libc/stdlib/malloc.c,v3retrieving revision 1.147.2.6.2.14retrieving revision 1.147.2.75diff -p -I __FBSDID -I $FreeBSD -u -r1.147.2.6.2.1 -r1.147.2.76--- lib/libc/stdlib/malloc.c 15 Apr 2009 03:14:26 -0000 1.147.2.6.2.17+++ lib/libc/stdlib/malloc.c 3 May 2009 17:51:38 -0000 1.147.2.78@@ -4715,16 +4715,41 @@ _malloc_thread_cleanup(void)9void10_malloc_prefork(void)11{12- unsigned i;13+ bool again;14+ unsigned i, j;15+ arena_t *larenas[narenas], *tarenas[narenas];1617/* Acquire all mutexes in a safe order. */1819- malloc_spin_lock(&arenas_lock);20- for (i = 0; i < narenas; i++) {21- if (arenas[i] != NULL)22- malloc_spin_lock(&arenas[i]->lock);23- }24- malloc_spin_unlock(&arenas_lock);25+ /*26+ * arenas_lock must be acquired after all of the arena mutexes, in27+ * order to avoid potential deadlock with arena_lock_balance[_hard]().28+ * Since arenas_lock protects the arenas array, the following code has29+ * to race with arenas_extend() callers until it succeeds in locking30+ * all arenas before locking arenas_lock.31+ */32+ memset(larenas, 0, sizeof(arena_t *) * narenas);33+ do {34+ again = false;35+36+ malloc_spin_lock(&arenas_lock);37+ for (i = 0; i < narenas; i++) {38+ if (arenas[i] != larenas[i]) {39+ memcpy(tarenas, arenas, sizeof(arena_t *) *40+ narenas);41+ malloc_spin_unlock(&arenas_lock);42+ for (j = 0; j < narenas; j++) {43+ if (larenas[j] != tarenas[j]) {44+ larenas[j] = tarenas[j];45+ malloc_spin_lock(46+ &larenas[j]->lock);47+ }48+ }49+ again = true;50+ break;51+ }52+ }53+ } while (again);5455malloc_mutex_lock(&base_mtx);5657@@ -4739,6 +4764,7 @@ void58_malloc_postfork(void)59{60unsigned i;61+ arena_t *larenas[narenas];6263/* Release all mutexes, now that fork() has completed. */6465@@ -4750,12 +4776,12 @@ _malloc_postfork(void)6667malloc_mutex_unlock(&base_mtx);6869- malloc_spin_lock(&arenas_lock);70+ memcpy(larenas, arenas, sizeof(arena_t *) * narenas);71+ malloc_spin_unlock(&arenas_lock);72for (i = 0; i < narenas; i++) {73- if (arenas[i] != NULL)74- malloc_spin_unlock(&arenas[i]->lock);75+ if (larenas[i] != NULL)76+ malloc_spin_unlock(&larenas[i]->lock);77}78- malloc_spin_unlock(&arenas_lock);79}8081/*828384