mirror of git://git.sysmocom.de/ofono
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.
This commit is contained in:
parent
db9b292f92
commit
8b8a760644
11
src/simfs.c
11
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));
|
||||
|
|
Loading…
Reference in New Issue