diff options
author | Scott Murray <scott.murray@konsulko.com> | 2020-07-22 14:40:17 -0400 |
---|---|---|
committer | Scott Murray <scott.murray@konsulko.com> | 2020-07-22 14:49:15 -0400 |
commit | cb8db512e462af970735aa86781ca2cfa58d0760 (patch) | |
tree | f0a5392715c3435c3af1a4ab6e168b961b353150 | |
parent | 5fdc7afba453f4f27b22364dd3c974eb9ec0ef46 (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.c | 25 |
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) |