kerneldevice,generic: avoid segfault when reported device doesn't exist

Could be a user error or a race condition. In any case, we shouldn't
crash.

    ModemManager[19677]: <debug> [1507235472.301934] Kernel event reported:
    ModemManager[19677]: <debug> [1507235472.301944]   action:    add
    ModemManager[19677]: <debug> [1507235472.301953]   subsystem: usbmisc
    ModemManager[19677]: <debug> [1507235472.301962]   name:      cdc-wdm0
    ModemManager[19677]: <debug> [1507235472.301970]   uid:       n/a
    ModemManager[19677]: <debug> [1507235472.301984] (usbmisc/cdc-wdm0) preloading contents and properties...
    ModemManager[19677]: <warn>  [1507235472.302007] Invalid sysfs path read for usbmisc/cdc-wdm0
    ModemManager[19677]: <debug> [1507235472.302017] (usbmisc/cdc-wdm0) interface class: 0x00
    ModemManager[19677]: <debug> [1507235472.302027] (usbmisc/cdc-wdm0) interface subclass: 0x00
    ModemManager[19677]: <debug> [1507235472.302037] (usbmisc/cdc-wdm0) interface protocol: 0x00
    ModemManager[19677]: <debug> [1507235472.302046] (usbmisc/cdc-wdm0) interface number (ID_USB_INTERFACE_NUM): 0x00
    ModemManager[19677]: <debug> [1507235472.302059] (usbmisc/cdc-wdm0) manufacturer: unknown
    ModemManager[19677]: <debug> [1507235472.302069] (usbmisc/cdc-wdm0) product: unknown
    ModemManager[19677]: <debug> [1507235472.302078] (usbmisc/cdc-wdm0) vid: unknown
    ModemManager[19677]: <debug> [1507235472.302088] (usbmisc/cdc-wdm0) pid: unknown

    (ModemManager:19677): GLib-CRITICAL **: g_str_has_prefix: assertion 'str != NULL' failed

    (ModemManager:19677): GLib-CRITICAL **: g_str_has_prefix: assertion 'str != NULL' failed

    (ModemManager:19677): GLib-CRITICAL **: g_str_has_prefix: assertion 'str != NULL' failed

    (ModemManager:19677): GLib-CRITICAL **: g_str_has_prefix: assertion 'str != NULL' failed

    Thread 1 "ModemManager" received signal SIGSEGV, Segmentation fault.
This commit is contained in:
Aleksander Morgado
2017-10-05 22:38:06 +02:00
parent 71730509ee
commit 5bb205d351

View File

@@ -611,11 +611,12 @@ check_condition (MMKernelDeviceGeneric *self,
/* Device sysfs path checks; we allow both a direct match and a prefix patch */ /* Device sysfs path checks; we allow both a direct match and a prefix patch */
if (g_str_equal (match->parameter, "DEVPATH")) { if (g_str_equal (match->parameter, "DEVPATH")) {
const gchar *sysfs_path;
gchar *prefix_match = NULL; gchar *prefix_match = NULL;
gboolean result = FALSE; gboolean result = FALSE;
sysfs_path = mm_kernel_device_get_sysfs_path (MM_KERNEL_DEVICE (self)); /* If sysfs path invalid (e.g. path doesn't exist), no match */
if (!self->priv->sysfs_path)
return FALSE;
/* If not already doing a prefix match, do an implicit one. This is so that /* If not already doing a prefix match, do an implicit one. This is so that
* we can add properties to the usb_device owning all ports, and then apply * we can add properties to the usb_device owning all ports, and then apply
@@ -623,22 +624,22 @@ check_condition (MMKernelDeviceGeneric *self,
if (match->value[0] && match->value[strlen (match->value) - 1] != '*') if (match->value[0] && match->value[strlen (match->value) - 1] != '*')
prefix_match = g_strdup_printf ("%s/*", match->value); prefix_match = g_strdup_printf ("%s/*", match->value);
if (string_match (sysfs_path, match->value) == condition_equal) { if (string_match (self->priv->sysfs_path, match->value) == condition_equal) {
result = TRUE; result = TRUE;
goto out; goto out;
} }
if (prefix_match && string_match (sysfs_path, prefix_match) == condition_equal) { if (prefix_match && string_match (self->priv->sysfs_path, prefix_match) == condition_equal) {
result = TRUE; result = TRUE;
goto out; goto out;
} }
if (g_str_has_prefix (sysfs_path, "/sys")) { if (g_str_has_prefix (self->priv->sysfs_path, "/sys")) {
if (string_match (&sysfs_path[4], match->value) == condition_equal) { if (string_match (&self->priv->sysfs_path[4], match->value) == condition_equal) {
result = TRUE; result = TRUE;
goto out; goto out;
} }
if (prefix_match && string_match (&sysfs_path[4], prefix_match) == condition_equal) { if (prefix_match && string_match (&self->priv->sysfs_path[4], prefix_match) == condition_equal) {
result = TRUE; result = TRUE;
goto out; goto out;
} }