summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/glib-2.0/glib-2.0/CVE-2019-9633_p2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/glib-2.0/glib-2.0/CVE-2019-9633_p2.patch')
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2019-9633_p2.patch231
1 files changed, 231 insertions, 0 deletions
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2019-9633_p2.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2019-9633_p2.patch
new file mode 100644
index 0000000000..3bb2f5d917
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2019-9633_p2.patch
@@ -0,0 +1,231 @@
1From d553d92d6e9f53cbe5a34166fcb919ba652c6a8e Mon Sep 17 00:00:00 2001
2From: Patrick Griffis <pgriffis@igalia.com>
3Date: Tue, 29 Jan 2019 10:07:06 -0500
4Subject: [PATCH] gsocketclient: Fix criticals
5
6This ensures the parent GTask is kept alive as long as an enumeration
7is running and trying to connect.
8
9Closes #1646
10Closes #1649
11
12Upstream-Status: Backport
13CVE: CVE-2019-9633 patch 2
14Affects: < 2.59.2
15Signed-off-by: Armin Kuster <akuster@mvista.com>
16
17---
18 gio/gsocketclient.c | 74 +++++++++++++++++++++++++++++-------------
19 gio/tests/gsocketclient-slow.c | 55 ++++++++++++++++++++++++++++++-
20 2 files changed, 106 insertions(+), 23 deletions(-)
21
22Index: glib-2.58.0/gio/gsocketclient.c
23===================================================================
24--- glib-2.58.0.orig/gio/gsocketclient.c
25+++ glib-2.58.0/gio/gsocketclient.c
26@@ -1327,7 +1327,7 @@ g_socket_client_connect_to_uri (GSocketC
27
28 typedef struct
29 {
30- GTask *task;
31+ GTask *task; /* unowned */
32 GSocketClient *client;
33
34 GSocketConnectable *connectable;
35@@ -1345,6 +1345,7 @@ static void connection_attempt_unref (gp
36 static void
37 g_socket_client_async_connect_data_free (GSocketClientAsyncConnectData *data)
38 {
39+ data->task = NULL;
40 g_clear_object (&data->connectable);
41 g_clear_object (&data->enumerator);
42 g_clear_object (&data->proxy_addr);
43@@ -1444,13 +1445,19 @@ set_last_error (GSocketClientAsyncConnec
44 }
45
46 static void
47-enumerator_next_async (GSocketClientAsyncConnectData *data)
48+enumerator_next_async (GSocketClientAsyncConnectData *data,
49+ gboolean add_task_ref)
50 {
51 /* We need to cleanup the state */
52 g_clear_object (&data->socket);
53 g_clear_object (&data->proxy_addr);
54 g_clear_object (&data->connection);
55
56+ /* Each enumeration takes a ref. This arg just avoids repeated unrefs when
57+ an enumeration starts another enumeration */
58+ if (add_task_ref)
59+ g_object_ref (data->task);
60+
61 g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVING, data->connectable, NULL);
62 g_socket_address_enumerator_next_async (data->enumerator,
63 g_task_get_cancellable (data->task),
64@@ -1478,7 +1485,7 @@ g_socket_client_tls_handshake_callback (
65 else
66 {
67 g_object_unref (object);
68- enumerator_next_async (data);
69+ enumerator_next_async (data, FALSE);
70 }
71 }
72
73@@ -1509,7 +1516,7 @@ g_socket_client_tls_handshake (GSocketCl
74 }
75 else
76 {
77- enumerator_next_async (data);
78+ enumerator_next_async (data, FALSE);
79 }
80 }
81
82@@ -1530,13 +1537,24 @@ g_socket_client_proxy_connect_callback (
83 }
84 else
85 {
86- enumerator_next_async (data);
87+ enumerator_next_async (data, FALSE);
88 return;
89 }
90
91 g_socket_client_tls_handshake (data);
92 }
93
94+static gboolean
95+task_completed_or_cancelled (GTask *task)
96+{
97+ if (g_task_get_completed (task))
98+ return TRUE;
99+ else if (g_task_return_error_if_cancelled (task))
100+ return TRUE;
101+ else
102+ return FALSE;
103+}
104+
105 static void
106 g_socket_client_connected_callback (GObject *source,
107 GAsyncResult *result,
108@@ -1549,8 +1567,7 @@ g_socket_client_connected_callback (GObj
109 GProxy *proxy;
110 const gchar *protocol;
111
112- /* data is NULL once the task is completed */
113- if (data && g_task_return_error_if_cancelled (data->task))
114+ if (g_cancellable_is_cancelled (attempt->cancellable) || task_completed_or_cancelled (data->task))
115 {
116 g_object_unref (data->task);
117 connection_attempt_unref (attempt);
118@@ -1570,17 +1587,15 @@ g_socket_client_connected_callback (GObj
119 {
120 clarify_connect_error (error, data->connectable, attempt->address);
121 set_last_error (data, error);
122+ connection_attempt_remove (attempt);
123+ enumerator_next_async (data, FALSE);
124 }
125 else
126- g_clear_error (&error);
127-
128- if (data)
129 {
130- connection_attempt_remove (attempt);
131- enumerator_next_async (data);
132+ g_clear_error (&error);
133+ g_object_unref (data->task);
134+ connection_attempt_unref (attempt);
135 }
136- else
137- connection_attempt_unref (attempt);
138
139 return;
140 }
141@@ -1592,7 +1607,6 @@ g_socket_client_connected_callback (GObj
142 {
143 ConnectionAttempt *attempt_entry = l->data;
144 g_cancellable_cancel (attempt_entry->cancellable);
145- attempt_entry->data = NULL;
146 connection_attempt_unref (attempt_entry);
147 }
148 g_slist_free (data->connection_attempts);
149@@ -1625,7 +1639,7 @@ g_socket_client_connected_callback (GObj
150 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
151 _("Proxying over a non-TCP connection is not supported."));
152
153- enumerator_next_async (data);
154+ enumerator_next_async (data, FALSE);
155 }
156 else if (g_hash_table_contains (data->client->priv->app_proxies, protocol))
157 {
158@@ -1652,7 +1666,7 @@ g_socket_client_connected_callback (GObj
159 _("Proxy protocol ā€œ%sā€ is not supported."),
160 protocol);
161
162- enumerator_next_async (data);
163+ enumerator_next_async (data, FALSE);
164 }
165 }
166
167@@ -1661,7 +1675,7 @@ on_connection_attempt_timeout (gpointer
168 {
169 ConnectionAttempt *attempt = data;
170
171- enumerator_next_async (attempt->data);
172+ enumerator_next_async (attempt->data, TRUE);
173
174 g_clear_pointer (&attempt->timeout_source, g_source_unref);
175 return G_SOURCE_REMOVE;
176@@ -1687,7 +1701,7 @@ g_socket_client_enumerator_callback (GOb
177 ConnectionAttempt *attempt;
178 GError *error = NULL;
179
180- if (g_task_return_error_if_cancelled (data->task))
181+ if (task_completed_or_cancelled (data->task))
182 {
183 g_object_unref (data->task);
184 return;
185@@ -1698,7 +1712,10 @@ g_socket_client_enumerator_callback (GOb
186 if (address == NULL)
187 {
188 if (data->connection_attempts)
189- return;
190+ {
191+ g_object_unref (data->task);
192+ return;
193+ }
194
195 g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL);
196 if (!error)
197@@ -1732,7 +1749,7 @@ g_socket_client_enumerator_callback (GOb
198 if (socket == NULL)
199 {
200 g_object_unref (address);
201- enumerator_next_async (data);
202+ enumerator_next_async (data, FALSE);
203 return;
204 }
205
206@@ -1804,11 +1821,24 @@ g_socket_client_connect_async (GSocketCl
207 else
208 data->enumerator = g_socket_connectable_enumerate (connectable);
209
210+ /* The flow and ownership here isn't quite obvious:
211+ - The task starts an async attempt to connect.
212+ - Each attempt holds a single ref on task.
213+ - Each attempt may create new attempts by timing out (not a failure) so
214+ there are multiple attempts happening in parallel.
215+ - Upon failure an attempt will start a new attempt that steals its ref
216+ until there are no more attempts left and it drops its ref.
217+ - Upon success it will cancel all other attempts and continue on
218+ to the rest of the connection (tls, proxies, etc) which do not
219+ happen in parallel and at the very end drop its ref.
220+ - Upon cancellation an attempt drops its ref.
221+ */
222+
223 data->task = g_task_new (client, cancellable, callback, user_data);
224 g_task_set_source_tag (data->task, g_socket_client_connect_async);
225 g_task_set_task_data (data->task, data, (GDestroyNotify)g_socket_client_async_connect_data_free);
226
227- enumerator_next_async (data);
228+ enumerator_next_async (data, FALSE);
229 }
230
231 /**