Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[worker] Use private copy of mode data. JB#45312
When a dynamic mode is activated from the worker thread, a pointer to
shared mode data is cached. If mode data gets invalidated due to the main
thread reloading configuration files, the worker thread will dereference
a stale pointer during mode deactivation.

Cache clone of mode data instead of just holding pointer to shared data.

Note that this only fixes logical error in expected behavior during
config reload, there is still race condition in mode data duplication
stage.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
  • Loading branch information
spiiroin committed Apr 9, 2019
1 parent 1b91629 commit 83df308
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/usb_moded-network.c
Expand Up @@ -1295,6 +1295,7 @@ int network_update(void)
LOG_REGISTER_CONTEXT;

if( control_get_cable_state() == CABLE_STATE_PC_CONNECTED ) {
// FIXME: data hazard
const modedata_t *data = worker_get_usb_mode_data();
if( data && data->network ) {
network_down(data);
Expand Down
9 changes: 5 additions & 4 deletions src/usb_moded-worker.c
Expand Up @@ -69,7 +69,7 @@ static bool worker_set_requested_mode_locked(const char *mode);
void worker_request_hardware_mode (const char *mode);
void worker_clear_hardware_mode (void);
static void worker_execute (void);
void worker_switch_to_mode (const char *mode);
static void worker_switch_to_mode (const char *mode);
static guint worker_add_iowatch (int fd, bool close_on_unref, GIOCondition cnd, GIOFunc io_cb, gpointer aptr);
static void *worker_thread_cb (void *aptr);
static gboolean worker_notify_cb (GIOChannel *chn, GIOCondition cnd, gpointer data);
Expand Down Expand Up @@ -391,7 +391,7 @@ void worker_clear_kernel_module(void)
* ------------------------------------------------------------------------- */

/** Contains the mode data */
static const modedata_t *worker_mode_data = NULL;
static modedata_t *worker_mode_data = NULL;

/** get the usb mode data
*
Expand All @@ -414,7 +414,8 @@ void worker_set_usb_mode_data(const modedata_t *data)
{
LOG_REGISTER_CONTEXT;

worker_mode_data = data;
modedata_free(worker_mode_data),
worker_mode_data = modedata_copy(data);
}

/* ------------------------------------------------------------------------- *
Expand Down Expand Up @@ -546,7 +547,7 @@ worker_execute(void)
* MODE_SWITCH
* ------------------------------------------------------------------------- */

void
static void
worker_switch_to_mode(const char *mode)
{
LOG_REGISTER_CONTEXT;
Expand Down
1 change: 0 additions & 1 deletion src/usb_moded-worker.h
Expand Up @@ -48,7 +48,6 @@ const modedata_t *worker_get_usb_mode_data (void);
void worker_set_usb_mode_data (const modedata_t *data);
void worker_request_hardware_mode(const char *mode);
void worker_clear_hardware_mode (void);
void worker_switch_to_mode (const char *mode);
bool worker_init (void);
void worker_quit (void);
void worker_wakeup (void);
Expand Down

0 comments on commit 83df308

Please sign in to comment.