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,
|
||||
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")) {
|
||||
g_autoptr(MMKernelDevice) kernel_device = NULL;
|
||||
|
||||
@@ -482,7 +493,7 @@ handle_uevent (MMBaseManager *self,
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -496,11 +507,20 @@ typedef struct {
|
||||
static gboolean
|
||||
start_device_added_idle (StartDeviceAdded *ctx)
|
||||
{
|
||||
MMKernelDevice *kernel_device;
|
||||
const gchar *subsystem;
|
||||
const gchar *name;
|
||||
|
||||
kernel_device = mm_kernel_device_udev_new (ctx->self->priv->udev, ctx->device);
|
||||
device_added (ctx->self, kernel_device, FALSE, ctx->manual_scan);
|
||||
g_object_unref (kernel_device);
|
||||
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);
|
||||
device_added (ctx->self, kernel_device, FALSE, ctx->manual_scan);
|
||||
}
|
||||
|
||||
g_object_unref (ctx->self);
|
||||
g_object_unref (ctx->device);
|
||||
|
Reference in New Issue
Block a user