On Thu, Feb 22, 2024 at 11:58 AM Daniel Lezcano <daniel.lezcano@xxxxxxxxxx> wrote: > > On 22/02/2024 11:52, Rafael J. Wysocki wrote: > > On Thu, Feb 22, 2024 at 11:47 AM Daniel Lezcano > > <daniel.lezcano@xxxxxxxxxx> wrote: > >> > >> On 14/02/2024 13:45, Rafael J. Wysocki wrote: > >>> From: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > >>> > >>> The current code requires thermal zone creators to pass pointers to > >>> writable ops structures to thermal_zone_device_register_with_trips() > >>> which needs to modify the target struct thermal_zone_device_ops object > >>> if the "critical" operation in it is NULL. > >>> > >>> Moreover, the callers of thermal_zone_device_register_with_trips() are > >>> required to hold on to the struct thermal_zone_device_ops object passed > >>> to it until the given thermal zone is unregistered. > >>> > >>> Both of these requirements are quite inconvenient, so modify struct > >>> thermal_zone_device to contain struct thermal_zone_device_ops as field and > >>> make thermal_zone_device_register_with_trips() copy the contents of the > >>> struct thermal_zone_device_ops passed to it via a pointer (which can be > >>> const now) to that field. > >>> > >>> Also adjust the code using thermal zone ops accordingly and modify > >>> thermal_of_zone_register() to use a local ops variable during > >>> thermal zone registration so ops do not need to be freed in > >>> thermal_of_zone_unregister() any more. > >> > >> [ ... ] > >> > >>> static void thermal_of_zone_unregister(struct thermal_zone_device *tz) > >>> { > >>> struct thermal_trip *trips = tz->trips; > >>> - struct thermal_zone_device_ops *ops = tz->ops; > >>> > >>> thermal_zone_device_disable(tz); > >>> thermal_zone_device_unregister(tz); > >>> kfree(trips); > >> > >> Not related to the current patch but with patch 1/6. Freeing the trip > >> points here will lead to a double free given it is already freed from > >> thermal_zone_device_unregister() after the changes introduces in patch > >> 1, right ? > > > > No, patch [1/6] doesn't free the caller-supplied ops, just copies them > > into the local instance. Attempting to free a static ops would not be > > a good idea, for example. > > I'm referring to the trip points not the ops. Ah, sorry for the confusion. > The patch 1 does: > > tz = kzalloc(struct_size(tz, trips, num_trips), GFP_KERNEL); > > Then the last line of thermal_zone_device_unregister() does: > > kfree(tz); > > That includes the trip points in the flexible array. Right. > Now in thermal_of_zone_unregister(), we do: > > trips = tz->trips; I missed this. > thermal_zone_device_unregister(tz); > kfree(trips); > > Hence double kfree, right? Indeed, so patch [1/6] is missing a thermal_of change to stop freeing trips separately. Let me send an update of just that patch.