summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Murray <scott.murray@konsulko.com>2020-07-22 14:40:17 -0400
committerScott Murray <scott.murray@konsulko.com>2020-07-22 14:49:15 -0400
commitcb8db512e462af970735aa86781ca2cfa58d0760 (patch)
treef0a5392715c3435c3af1a4ab6e168b961b353150
parent5fdc7afba453f4f27b22364dd3c974eb9ec0ef46 (diff)
Switch to refcounted allocation for init datajellyfish_9.99.2jellyfish/9.99.29.99.2
When running in qemu, there seems to be a rare race condition where the timeout waiting on BlueZ during init happens with the timing such that bluetooth_func doesn't finish before init returns, resulting in an invalid access to the init_data structure that was on the init function's stack. To fix this, init_data is now allocated and refcounted using glib's atomic refcounted memory allocator API. Bug-AGL: SPEC-3301 Signed-off-by: Scott Murray <scott.murray@konsulko.com> Change-Id: I1ea8831ca5c008a2916909671e62cbd770906e5e
-rw-r--r--binding/bluetooth-api.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/binding/bluetooth-api.c b/binding/bluetooth-api.c
index 8e4e1f9..6484b18 100644
--- a/binding/bluetooth-api.c
+++ b/binding/bluetooth-api.c
@@ -630,6 +630,8 @@ static gpointer bluetooth_func(gpointer ptr)
GMainLoop *loop;
int rc = 0;
+ g_atomic_rc_box_acquire(id);
+
loop = g_main_loop_new(NULL, FALSE);
if (!loop) {
AFB_ERROR("Unable to create main loop");
@@ -675,6 +677,7 @@ static gpointer bluetooth_func(gpointer ptr)
bluetooth_cleanup(ns);
afb_api_set_userdata(id->api, NULL);
+ g_atomic_rc_box_release(id);
return NULL;
@@ -686,18 +689,24 @@ err_no_ns:
err_no_loop:
signal_init_done(id, -1);
+ g_atomic_rc_box_release(id);
return NULL;
}
static int init(afb_api_t api)
{
- struct init_data init_data, *id = &init_data;
+ struct init_data *id = NULL;
json_object *args = NULL;
gint64 end_time;
int ret;
+ gboolean init_done;
+
+ id = g_atomic_rc_box_new0(struct init_data);
+ if (!id)
+ return -ENOMEM;
+ g_atomic_rc_box_acquire(id);
- memset(id, 0, sizeof(*id));
id->init_done = FALSE;
id->rc = 0;
id->api = api;
@@ -737,20 +746,22 @@ static int init(afb_api_t api)
if (!g_cond_wait_until(&id->cond, &id->mutex, end_time))
break;
}
+ ret = id->rc;
+ init_done = id->init_done;
g_mutex_unlock(&id->mutex);
+ g_atomic_rc_box_release(id);
- if (!id->init_done) {
+ if (!init_done) {
AFB_ERROR("bluetooth-binding init timeout");
return -1;
}
- if (id->rc)
- AFB_ERROR("bluetooth-binding init thread returned %d",
- id->rc);
+ if (ret)
+ AFB_ERROR("bluetooth-binding init thread returned %d", ret);
else
AFB_INFO("bluetooth-binding operational");
- return id->rc;
+ return ret;
}
static void mediaplayer1_send_event(struct bluetooth_state *ns)