base-manager: ensure all GUdevDevices have subsystem and name set
Under certain rare conditions (e.g. race between querying devices of a given subsystem and the kernel tearing those devices down), the subsystem reported for a GUdevDevice seems to be NULL. So, ensure both subsystem and name are set on the GUdevDevice before we process them. The issue has been observed on GUdevDevices listed by g_udev_client_query_by_subsystem(), not on the ones asynchronously reported via uevents, but we add the validity check on both places for consistency. Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/343
This commit is contained in:
@@ -473,6 +473,17 @@ handle_uevent (MMBaseManager *self,
|
|||||||
const gchar *action,
|
const gchar *action,
|
||||||
GUdevDevice *device)
|
GUdevDevice *device)
|
||||||
{
|
{
|
||||||
|
const gchar *subsystem;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
|
subsystem = g_udev_device_get_subsystem (device);
|
||||||
|
name = g_udev_device_get_name (device);
|
||||||
|
|
||||||
|
/* Valid udev devices must have subsystem and name set; if they don't have
|
||||||
|
* both things, we silently ignore them. */
|
||||||
|
if (!subsystem || !name)
|
||||||
|
return;
|
||||||
|
|
||||||
if (g_str_equal (action, "add") || g_str_equal (action, "move") || g_str_equal (action, "change")) {
|
if (g_str_equal (action, "add") || g_str_equal (action, "move") || g_str_equal (action, "change")) {
|
||||||
g_autoptr(MMKernelDevice) kernel_device = NULL;
|
g_autoptr(MMKernelDevice) kernel_device = NULL;
|
||||||
|
|
||||||
@@ -482,7 +493,7 @@ handle_uevent (MMBaseManager *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (g_str_equal (action, "remove")) {
|
if (g_str_equal (action, "remove")) {
|
||||||
device_removed (self, g_udev_device_get_subsystem (device), g_udev_device_get_name (device));
|
device_removed (self, subsystem, name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -496,11 +507,20 @@ typedef struct {
|
|||||||
static gboolean
|
static gboolean
|
||||||
start_device_added_idle (StartDeviceAdded *ctx)
|
start_device_added_idle (StartDeviceAdded *ctx)
|
||||||
{
|
{
|
||||||
MMKernelDevice *kernel_device;
|
const gchar *subsystem;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
|
subsystem = g_udev_device_get_subsystem (ctx->device);
|
||||||
|
name = g_udev_device_get_name (ctx->device);
|
||||||
|
|
||||||
|
/* Valid udev devices must have subsystem and name set; if they don't have
|
||||||
|
* both things, we silently ignore them. */
|
||||||
|
if (subsystem && name) {
|
||||||
|
g_autoptr(MMKernelDevice) kernel_device = NULL;
|
||||||
|
|
||||||
kernel_device = mm_kernel_device_udev_new (ctx->self->priv->udev, ctx->device);
|
kernel_device = mm_kernel_device_udev_new (ctx->self->priv->udev, ctx->device);
|
||||||
device_added (ctx->self, kernel_device, FALSE, ctx->manual_scan);
|
device_added (ctx->self, kernel_device, FALSE, ctx->manual_scan);
|
||||||
g_object_unref (kernel_device);
|
}
|
||||||
|
|
||||||
g_object_unref (ctx->self);
|
g_object_unref (ctx->self);
|
||||||
g_object_unref (ctx->device);
|
g_object_unref (ctx->device);
|
||||||
|
Reference in New Issue
Block a user