Lines 1-4
Link Here
|
1 |
From 22656f16c29591207c667362e2a42fd348fe8494 Mon Sep 17 00:00:00 2001 |
1 |
From 165c867f83b7c479a0352b8adde900f36739dcc6 Mon Sep 17 00:00:00 2001 |
2 |
From: Martin Pieuchot <mpi@openbsd.org> |
2 |
From: Martin Pieuchot <mpi@openbsd.org> |
3 |
Date: Fri, 28 Apr 2017 15:06:52 +0200 |
3 |
Date: Fri, 28 Apr 2017 15:06:52 +0200 |
4 |
Subject: [PATCH] kqueue: fix use-after-free of ``kqueue_sub''. |
4 |
Subject: [PATCH] kqueue: fix use-after-free of ``kqueue_sub''. |
Lines 11-23
Link Here
|
11 |
To prevent such crash, make sure the threads are holding ``hash_lock'' |
11 |
To prevent such crash, make sure the threads are holding ``hash_lock'' |
12 |
when manipulating such items. |
12 |
when manipulating such items. |
13 |
--- |
13 |
--- |
14 |
gio/kqueue/kqueue-helper.c | 6 ++++-- |
14 |
gio/kqueue/gkqueuefilemonitor.c | 14 ++++++++++++++ |
15 |
1 file changed, 4 insertions(+), 2 deletions(-) |
15 |
gio/kqueue/kqueue-helper.c | 10 +++++----- |
|
|
16 |
2 files changed, 19 insertions(+), 5 deletions(-) |
16 |
|
17 |
|
|
|
18 |
diff --git a/gio/kqueue/gkqueuefilemonitor.c b/gio/kqueue/gkqueuefilemonitor.c |
19 |
index 78b749637..bd55e2e70 100644 |
20 |
--- gio/kqueue/gkqueuefilemonitor.c |
21 |
+++ gio/kqueue/gkqueuefilemonitor.c |
22 |
@@ -30,6 +30,16 @@ |
23 |
#include <gio/giomodule.h> |
24 |
|
25 |
|
26 |
+/* |
27 |
+ * Because ``kqueue_sub'' are not refcounted, we need |
28 |
+ * ensure no other thread is getting a reference to |
29 |
+ * the element we want to free. |
30 |
+ * |
31 |
+ * That's why _kh_cancel_sub() must be called with |
32 |
+ * this lock held to prevent a race. |
33 |
+ */ |
34 |
+G_LOCK_EXTERN (hash_lock); |
35 |
+ |
36 |
struct _GKqueueFileMonitor |
37 |
{ |
38 |
GLocalFileMonitor parent_instance; |
39 |
@@ -80,9 +90,11 @@ g_kqueue_file_monitor_finalize (GObject *object) |
40 |
|
41 |
if (kqueue_monitor->sub) |
42 |
{ |
43 |
+ G_LOCK (hash_lock); |
44 |
_kh_cancel_sub (kqueue_monitor->sub); |
45 |
_kh_sub_free (kqueue_monitor->sub); |
46 |
kqueue_monitor->sub = NULL; |
47 |
+ G_UNLOCK (hash_lock); |
48 |
} |
49 |
|
50 |
if (kqueue_monitor->fallback) |
51 |
@@ -181,9 +193,11 @@ g_kqueue_file_monitor_cancel (GFileMonitor *monitor) |
52 |
|
53 |
if (kqueue_monitor->sub) |
54 |
{ |
55 |
+ G_LOCK (hash_lock); |
56 |
_kh_cancel_sub (kqueue_monitor->sub); |
57 |
_kh_sub_free (kqueue_monitor->sub); |
58 |
kqueue_monitor->sub = NULL; |
59 |
+ G_UNLOCK (hash_lock); |
60 |
} |
61 |
else if (kqueue_monitor->fallback) |
62 |
{ |
17 |
diff --git a/gio/kqueue/kqueue-helper.c b/gio/kqueue/kqueue-helper.c |
63 |
diff --git a/gio/kqueue/kqueue-helper.c b/gio/kqueue/kqueue-helper.c |
18 |
index d4e66cd4d..84b9ef164 100644 |
64 |
index d4e66cd4d..f8267464b 100644 |
19 |
--- gio/kqueue/kqueue-helper.c |
65 |
--- gio/kqueue/kqueue-helper.c |
20 |
+++ gio/kqueue/kqueue-helper.c |
66 |
+++ gio/kqueue/kqueue-helper.c |
|
|
67 |
@@ -43,7 +43,7 @@ static gboolean kh_debug_enabled = FALSE; |
68 |
#define KH_W if (kh_debug_enabled) g_warning |
69 |
|
70 |
static GHashTable *subs_hash_table = NULL; |
71 |
-G_LOCK_DEFINE_STATIC (hash_lock); |
72 |
+G_LOCK_DEFINE (hash_lock); |
73 |
|
74 |
static int kqueue_descriptor = -1; |
75 |
static int kqueue_socket_pair[] = {-1, -1}; |
21 |
@@ -291,10 +291,10 @@ process_kqueue_notifications (GIOChannel *gioc, |
76 |
@@ -291,10 +291,10 @@ process_kqueue_notifications (GIOChannel *gioc, |
22 |
|
77 |
|
23 |
G_LOCK (hash_lock); |
78 |
G_LOCK (hash_lock); |
Lines 54-59
Link Here
|
54 |
return TRUE; |
109 |
return TRUE; |
55 |
} |
110 |
} |
56 |
|
111 |
|
|
|
112 |
@@ -504,9 +506,7 @@ _kh_cancel_sub (kqueue_sub *sub) |
113 |
|
114 |
_km_remove (sub); |
115 |
|
116 |
- G_LOCK (hash_lock); |
117 |
removed = g_hash_table_remove (subs_hash_table, GINT_TO_POINTER (sub->fd)); |
118 |
- G_UNLOCK (hash_lock); |
119 |
|
120 |
if (removed) |
121 |
{ |
57 |
-- |
122 |
-- |
58 |
2.12.2 |
123 |
2.12.2 |
59 |
|
124 |
|