aboutsummaryrefslogtreecommitdiff
path: root/src/mm-generic-cdma.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2010-01-19 03:16:34 -0800
committerDan Williams <dcbw@redhat.com>2010-01-19 03:18:10 -0800
commit50ad39b28e61adb3d9da178c47e41100f554adeb (patch)
tree0dad5f389015412d5f6c0ecd02fd6ec6d486e9c4 /src/mm-generic-cdma.c
parent73e10c77d37791ed4a1f51ee8c1007600ef24bde (diff)
core: protect against modem removal in critical callbacks (rh #553953)
There are more places to handle, but these are the most critical. If the modem is removed while a command is in-progress, the mm-callback-info code will set info->modem to NULL. Make sure we check for that in callbacks and return a reasonable error. Previous code would just blindly forge ahead and die on a null dereference.
Diffstat (limited to 'src/mm-generic-cdma.c')
-rw-r--r--src/mm-generic-cdma.c77
1 files changed, 41 insertions, 36 deletions
diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c
index 7122c483..e3c6004f 100644
--- a/src/mm-generic-cdma.c
+++ b/src/mm-generic-cdma.c
@@ -11,7 +11,7 @@
* GNU General Public License for more details:
*
* Copyright (C) 2008 - 2009 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 - 2010 Red Hat, Inc.
*/
#include <string.h>
@@ -478,13 +478,15 @@ static void
disable_all_done (MMModem *modem, GError *error, gpointer user_data)
{
MMCallbackInfo *info = user_data;
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- if (error) {
- disable_set_previous_state (MM_MODEM (modem), info);
- info->error = g_error_copy (error);
+ info->error = mm_modem_check_removed (modem, error);
+ if (info->error) {
+ if (modem)
+ disable_set_previous_state (modem, info);
} else {
+ MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
+ MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
+
mm_serial_port_close (priv->primary);
mm_modem_set_state (modem, MM_MODEM_STATE_DISABLED, MM_MODEM_STATE_REASON_NONE);
@@ -501,18 +503,22 @@ disable_flash_done (MMSerialPort *port,
gpointer user_data)
{
MMCallbackInfo *info = user_data;
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
+ MMGenericCdma *self;
- if (error) {
- disable_set_previous_state (info->modem, info);
- info->error = g_error_copy (error);
+ info->error = mm_modem_check_removed (info->modem, error);
+ if (info->error) {
+ if (info->modem)
+ disable_set_previous_state (info->modem, info);
mm_callback_info_schedule (info);
- } else {
- if (MM_GENERIC_CDMA_GET_CLASS (self)->post_disable)
- MM_GENERIC_CDMA_GET_CLASS (self)->post_disable (self, disable_all_done, info);
- else
- disable_all_done (MM_MODEM (self), NULL, info);
+ return;
}
+
+ self = MM_GENERIC_CDMA (info->modem);
+
+ if (MM_GENERIC_CDMA_GET_CLASS (self)->post_disable)
+ MM_GENERIC_CDMA_GET_CLASS (self)->post_disable (self, disable_all_done, info);
+ else
+ disable_all_done (MM_MODEM (self), NULL, info);
}
static void
@@ -557,13 +563,15 @@ dial_done (MMSerialPort *port,
gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);;
- if (error) {
- info->error = g_error_copy (error);
- update_enabled_state (MM_GENERIC_CDMA (info->modem), FALSE, MM_MODEM_STATE_REASON_NONE);
+ info->error = mm_modem_check_removed (info->modem, error);
+ if (info->error) {
+ if (info->modem)
+ update_enabled_state (MM_GENERIC_CDMA (info->modem), FALSE, MM_MODEM_STATE_REASON_NONE);
} else {
+ MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
+ MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
+
/* Clear reg tries; we're obviously registered by this point */
registration_cleanup (self, 0, 0);
@@ -598,25 +606,22 @@ disconnect_flash_done (MMSerialPort *port,
gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem);
-
- if (error) {
- MMModemState prev_state;
-
- /* Reset old state since the operation failed */
- prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_CDMA_PREV_STATE_TAG));
- mm_modem_set_state (MM_MODEM (info->modem),
- prev_state,
- MM_MODEM_STATE_REASON_NONE);
+ MMModemState prev_state;
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- return;
+ info->error = mm_modem_check_removed (info->modem, error);
+ if (info->error) {
+ if (info->modem) {
+ /* Reset old state since the operation failed */
+ prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_CDMA_PREV_STATE_TAG));
+ mm_modem_set_state (MM_MODEM (info->modem),
+ prev_state,
+ MM_MODEM_STATE_REASON_NONE);
+ }
+ } else {
+ mm_port_set_connected (MM_GENERIC_CDMA_GET_PRIVATE (info->modem)->data, FALSE);
+ update_enabled_state (MM_GENERIC_CDMA (info->modem), FALSE, MM_MODEM_STATE_REASON_NONE);
}
- mm_port_set_connected (priv->data, FALSE);
- update_enabled_state (MM_GENERIC_CDMA (info->modem), FALSE, MM_MODEM_STATE_REASON_NONE);
-
mm_callback_info_schedule (info);
}