Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-doc
Path: blob/main/website/static/security/patches/EN-09:04/fork.patch
18096 views
1
Index: lib/libc/stdlib/malloc.c
2
===================================================================
3
RCS file: /home/ncvs/src/lib/libc/stdlib/malloc.c,v
4
retrieving revision 1.147.2.6.2.1
5
retrieving revision 1.147.2.7
6
diff -p -I __FBSDID -I $FreeBSD -u -r1.147.2.6.2.1 -r1.147.2.7
7
--- lib/libc/stdlib/malloc.c 15 Apr 2009 03:14:26 -0000 1.147.2.6.2.1
8
+++ lib/libc/stdlib/malloc.c 3 May 2009 17:51:38 -0000 1.147.2.7
9
@@ -4715,16 +4715,41 @@ _malloc_thread_cleanup(void)
10
void
11
_malloc_prefork(void)
12
{
13
- unsigned i;
14
+ bool again;
15
+ unsigned i, j;
16
+ arena_t *larenas[narenas], *tarenas[narenas];
17
18
/* Acquire all mutexes in a safe order. */
19
20
- malloc_spin_lock(&arenas_lock);
21
- for (i = 0; i < narenas; i++) {
22
- if (arenas[i] != NULL)
23
- malloc_spin_lock(&arenas[i]->lock);
24
- }
25
- malloc_spin_unlock(&arenas_lock);
26
+ /*
27
+ * arenas_lock must be acquired after all of the arena mutexes, in
28
+ * order to avoid potential deadlock with arena_lock_balance[_hard]().
29
+ * Since arenas_lock protects the arenas array, the following code has
30
+ * to race with arenas_extend() callers until it succeeds in locking
31
+ * all arenas before locking arenas_lock.
32
+ */
33
+ memset(larenas, 0, sizeof(arena_t *) * narenas);
34
+ do {
35
+ again = false;
36
+
37
+ malloc_spin_lock(&arenas_lock);
38
+ for (i = 0; i < narenas; i++) {
39
+ if (arenas[i] != larenas[i]) {
40
+ memcpy(tarenas, arenas, sizeof(arena_t *) *
41
+ narenas);
42
+ malloc_spin_unlock(&arenas_lock);
43
+ for (j = 0; j < narenas; j++) {
44
+ if (larenas[j] != tarenas[j]) {
45
+ larenas[j] = tarenas[j];
46
+ malloc_spin_lock(
47
+ &larenas[j]->lock);
48
+ }
49
+ }
50
+ again = true;
51
+ break;
52
+ }
53
+ }
54
+ } while (again);
55
56
malloc_mutex_lock(&base_mtx);
57
58
@@ -4739,6 +4764,7 @@ void
59
_malloc_postfork(void)
60
{
61
unsigned i;
62
+ arena_t *larenas[narenas];
63
64
/* Release all mutexes, now that fork() has completed. */
65
66
@@ -4750,12 +4776,12 @@ _malloc_postfork(void)
67
68
malloc_mutex_unlock(&base_mtx);
69
70
- malloc_spin_lock(&arenas_lock);
71
+ memcpy(larenas, arenas, sizeof(arena_t *) * narenas);
72
+ malloc_spin_unlock(&arenas_lock);
73
for (i = 0; i < narenas; i++) {
74
- if (arenas[i] != NULL)
75
- malloc_spin_unlock(&arenas[i]->lock);
76
+ if (larenas[i] != NULL)
77
+ malloc_spin_unlock(&larenas[i]->lock);
78
}
79
- malloc_spin_unlock(&arenas_lock);
80
}
81
82
/*
83
84