[PATCH] mm-base-manager: ref MMDevice before releasing port
Dan Williams
dcbw at redhat.com
Thu Feb 22 16:55:27 UTC 2018
On Wed, 2018-02-21 at 13:49 -0800, Eric Caruso wrote:
> Releasing the port on the device looks benign but because it emits
> a signal, it could call device_context_port_released and unref the
> MMDevice in port_context_unref. This means the MMDevice might be
> disposed before we get to the g_object_ref and the subsequent call
> to g_hash_table_remove will try to hash a null string, which makes
> MM crash.
The refcounting looks a bit convoluted in the existing code, but the
patch LGTM for now.
Dan
> ---
> src/mm-base-manager.c | 30 +++++++++++++++---------------
> 1 file changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c
> index 4b92ab0b..7738ce0d 100644
> --- a/src/mm-base-manager.c
> +++ b/src/mm-base-manager.c
> @@ -220,28 +220,28 @@ device_removed (MMBaseManager *self,
> /* Handle tty/net/wdm port removal */
> device = find_device_by_port (self, kernel_device);
> if (device) {
> + /* The callbacks triggered when the port is released or
> device support is
> + * cancelled may end up unreffing the device or removing
> it from the HT, and
> + * so in order to make sure the reference is still valid
> when we call
> + * support_check_cancel() and g_hash_table_remove(), we
> hold a full reference
> + * ourselves. */
> + g_object_ref (device);
> +
> mm_info ("(%s/%s): released by device '%s'", subsys,
> name, mm_device_get_uid (device));
> mm_device_release_port (device, kernel_device);
>
> /* If port probe list gets empty, remove the device
> object iself */
> if (!mm_device_peek_port_probe_list (device)) {
> - /* The callback triggered when the device support is
> cancelled may end up
> - * removing the device from the HT, and that was the
> last full reference
> - * we kept. So, in order to make sure the reference
> is still valid after
> - * support_check_cancel(), we hold a full reference
> ourselves. */
> mm_dbg ("Removing empty device '%s'",
> mm_device_get_uid (device));
> - g_object_ref (device);
> - {
> - if
> (mm_plugin_manager_device_support_check_cancel (self->priv-
> >plugin_manager, device))
> - mm_dbg ("Device support check has been
> cancelled");
> -
> - /* The device may have already been removed from
> the tracking HT, we
> - * just try to remove it and if it fails, we
> ignore it */
> - mm_device_remove_modem (device);
> - g_hash_table_remove (self->priv->devices,
> mm_device_get_uid (device));
> - }
> - g_object_unref (device);
> + if (mm_plugin_manager_device_support_check_cancel
> (self->priv->plugin_manager, device))
> + mm_dbg ("Device support check has been
> cancelled");
> +
> + /* The device may have already been removed from the
> tracking HT, we
> + * just try to remove it and if it fails, we ignore
> it */
> + mm_device_remove_modem (device);
> + g_hash_table_remove (self->priv->devices,
> mm_device_get_uid (device));
> }
> + g_object_unref (device);
> }
>
> return;
More information about the ModemManager-devel
mailing list