summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2017-04-03 12:46:37 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2017-04-05 20:44:11 +0000
commit89d663d94a12439ecc5ab0cc68b13e92906309c2 (patch)
treea99ae7f1ee0bf4aff597d085d01c9e94edc93a84
parenta0e15ecbedcfe86e544fb74f1d909af0d43ddbf9 (diff)
downloadostree-89d663d94a12439ecc5ab0cc68b13e92906309c2.tar.gz
soup: Hold a ref to the pending URI during completion processing
It was reported that in the range request handling, we called `remove_pending()` twice (once in processing it, and once potentially in the local_error cleanup), and this could be viewed as a use-after-free. However, right now the range cleanup and `local_error` being set are mututally exclusive. Further, the task object already holds a strong reference, so I observed the refcount was 2. For both of these reasons, there is no use-after-free in practice. Reported-By: "Siddharth Sharma" <siddharth@redhat.com> Closes: #774 Approved by: jlebon
-rw-r--r--src/libostree/ostree-fetcher-soup.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/src/libostree/ostree-fetcher-soup.c b/src/libostree/ostree-fetcher-soup.c
index b130b48c..fdcbea52 100644
--- a/src/libostree/ostree-fetcher-soup.c
+++ b/src/libostree/ostree-fetcher-soup.c
@@ -1040,21 +1040,21 @@ on_request_sent (GObject *object,
gpointer user_data)
{
GTask *task = G_TASK (user_data);
- OstreeFetcherPendingURI *pending;
- GCancellable *cancellable;
+ /* Hold a ref to the pending across this function, since we remove
+ * it from the hash early in some cases, not in others. */
+ OstreeFetcherPendingURI *pending = pending_uri_ref (g_task_get_task_data (task));
+ GCancellable *cancellable = g_task_get_cancellable (task);
GError *local_error = NULL;
glnx_unref_object SoupMessage *msg = NULL;
- pending = g_task_get_task_data (task);
- cancellable = g_task_get_cancellable (task);
-
pending->state = OSTREE_FETCHER_STATE_COMPLETE;
pending->request_body = soup_request_send_finish ((SoupRequest*) object,
result, &local_error);
if (!pending->request_body)
goto out;
-
+ g_assert_no_error (local_error);
+
if (SOUP_IS_REQUEST_HTTP (object))
{
msg = soup_request_http_get_message ((SoupRequestHTTP*) object);
@@ -1183,6 +1183,7 @@ on_request_sent (GObject *object,
remove_pending (pending);
}
+ pending_uri_unref (pending);
g_object_unref (task);
}