From 8b8a760644fd99f8df295fe4dbcd23d75da8b171 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Thu, 29 Mar 2018 09:46:22 -0500 Subject: [PATCH] simfs: Fix crash in sim_fs_op_free If an operation is in progress and an operation is canceled, we don't actually destroy it, but simply clear out the callback. In the case of a context being destroyed, the operation is left on the simfs op_q with a dangling pointer to the already freed context. So the current logic in sim_fs_op_free tries to access invalid memory. Fix this by performing the watch operations in sim_fs_end_current instead and setting the context pointer appropriately. --- src/simfs.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/simfs.c b/src/simfs.c index c7ddbb38..439e62d0 100644 --- a/src/simfs.c +++ b/src/simfs.c @@ -95,11 +95,6 @@ struct sim_fs { static void sim_fs_op_free(gpointer pointer) { struct sim_fs_op *node = pointer; - struct sim_fs *fs = node->context->fs; - - /* only release the session if there are no pending reads */ - if (fs->watch_id && g_queue_is_empty(fs->op_q)) - __ofono_sim_remove_session_watch(fs->session, fs->watch_id); g_free(node->buffer); g_free(node); @@ -127,6 +122,9 @@ void sim_fs_free(struct sim_fs *fs) while (fs->contexts) sim_fs_context_free(fs->contexts->data); + if (fs->watch_id) + __ofono_sim_remove_session_watch(fs->session, fs->watch_id); + g_free(fs); } @@ -197,6 +195,7 @@ void sim_fs_context_free(struct ofono_sim_context *context) if (n == 0) { op->cb = NULL; + op->context = NULL; n += 1; continue; @@ -272,6 +271,8 @@ static void sim_fs_end_current(struct sim_fs *fs) if (g_queue_get_length(fs->op_q) > 0) fs->op_source = g_idle_add(sim_fs_op_next, fs); + else if (fs->watch_id) /* release the session if no pending reads */ + __ofono_sim_remove_session_watch(fs->session, fs->watch_id); if (fs->fd != -1) { TFR(close(fs->fd));