* resource leak in firmware/arm_scmi driver @ 2022-10-10 8:45 Uwe Kleine-König 2022-10-13 11:48 ` Cristian Marussi 0 siblings, 1 reply; 3+ messages in thread From: Uwe Kleine-König @ 2022-10-10 8:45 UTC (permalink / raw) To: Sudeep Holla, Cristian Marussi; +Cc: linux-arm-kernel, kernel [-- Attachment #1.1: Type: text/plain, Size: 984 bytes --] Hello, during some janitorial cleanup I stumbled over a resource leak in drivers/firmware/arm_scmi/driver.c. The problem is as follows: scmi_remove() might return early if info->users is non-zero. The driver core however ignores the return value of scmi_remove() and removes the device and frees the devm-allocated resources (e.g. *info). So letting aside that some resources are never freed after a failed call of scmi_remove(), the user of the scmi node will probably stumble over accessing freed memory soon. I wouldn't be surprised if that was exploitable. I quickly tried to fix this issue, but didn't understand the driver good enough. I think a fix would involve adding a get_device() call to scmi_handle_get() to prevent scmi_remove() being called while a handle exists. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ | [-- Attachment #1.2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 176 bytes --] _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: resource leak in firmware/arm_scmi driver 2022-10-10 8:45 resource leak in firmware/arm_scmi driver Uwe Kleine-König @ 2022-10-13 11:48 ` Cristian Marussi 2022-10-13 15:49 ` Uwe Kleine-König 0 siblings, 1 reply; 3+ messages in thread From: Cristian Marussi @ 2022-10-13 11:48 UTC (permalink / raw) To: Uwe Kleine-König; +Cc: Sudeep Holla, linux-arm-kernel, kernel On Mon, Oct 10, 2022 at 10:45:45AM +0200, Uwe Kleine-König wrote: > Hello, > Hi Uwe, thanks for reporting this. > during some janitorial cleanup I stumbled over a resource leak in > drivers/firmware/arm_scmi/driver.c. > > The problem is as follows: > > scmi_remove() might return early if info->users is non-zero. The driver > core however ignores the return value of scmi_remove() and removes the > device and frees the devm-allocated resources (e.g. *info). > > So letting aside that some resources are never freed after a failed call > of scmi_remove(), the user of the scmi node will probably stumble over > accessing freed memory soon. I wouldn't be surprised if that was > exploitable. > At first, I thought that this was only some kind of mess that needed to be cleaned up in the remove/exit path but without any real way of being exposed: this *bad* assumption of mine came from the fact that the SCMI drivers (like scmi-cpufreq scmi-hwmon) register to use the core SCMI stack services using an exported symbol (scmi_register_driver) and then, additionally, each SCMI driver willing to use some the core SCMI protocols issues a try_module_get (since the protocols could have been modularized) So that in a module scenario (with scmi-module being the core platform driver: root@deb-buster-arm64:~# lsmod Module Size Used by scmi_hwmon 16384 0 scmi_module 131072 2 scmi_hwmon root@deb-buster-arm64:~# rmmod ./scmi-module.ko rmmod: ERROR: Module scmi_module is in use by: scmi_hwmon BUT, then I realized that all of this refcounting is not going to save me from an explicitly triggered unbind: root@deb-buster-arm64:~# echo 'firmware:scmi' > /sys/bus/platform/drivers/arm-scmi/unbind [11601.798671] arm-scmi firmware:scmi: remove callback returned a non-zero value. This will be ignored. This will indeed expose the issue you reported. > I quickly tried to fix this issue, but didn't understand the driver good > enough. I think a fix would involve adding a get_device() call to > scmi_handle_get() to prevent scmi_remove() being called while a handle > exists. > I tried to address the issue with the get_device() calls as you suggested, but it has really no effect and in fact looking at the code on the remove path there is nothing that seems to be taken into consideration to stop a removal (and this indeed is consistent with the fact that any error returned on the removal/exit path is effectively ignored). What instead DOES seem to work, it is to add a proper devlink with device_link_add() declaring any SCMI driver device (like from cpufreq) as a consumer of the core stack platform device: this will NOT stop the removal, BUT it does trigger an implicit unbind at first of all the SCMI drivers currently loaded when an unbind is requested for the core SCMI platform device: as a consequence the removal can now be triggered safely by an unbind even if some SCMI driver users are present (they will be unbound too) Now, for this cleanup to fully work, some (long due) rework of the SCMI core devices handling and removal is needed (and it has partially already started in other unrelated series), so my plan would be to, at first, immediately add a '.suppress_bind_attrs = true' to the core driver to mitigate this (which is also easily portable to stable) and then rework properly the core SCMI removeal routines to safely re-enable a proper unbind. (or not re-enabling it if deemed not worth BUT anyway reworking the core SCMI remove/exit path) I'll check my plan with Sudeep, any thoughts from you about this ? Am I missing something more ? Thanks a lot. Regards, Cristian _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: resource leak in firmware/arm_scmi driver 2022-10-13 11:48 ` Cristian Marussi @ 2022-10-13 15:49 ` Uwe Kleine-König 0 siblings, 0 replies; 3+ messages in thread From: Uwe Kleine-König @ 2022-10-13 15:49 UTC (permalink / raw) To: Cristian Marussi Cc: kernel, linux-arm-kernel, Sudeep Holla, Rafael J. Wysocki, Greg Kroah-Hartman [-- Attachment #1.1: Type: text/plain, Size: 4349 bytes --] Hello Cristian, adding Rafael and Greg to Cc:; maybe they can add some nice alternative. On Thu, Oct 13, 2022 at 12:48:03PM +0100, Cristian Marussi wrote: > On Mon, Oct 10, 2022 at 10:45:45AM +0200, Uwe Kleine-König wrote: > > during some janitorial cleanup I stumbled over a resource leak in > > drivers/firmware/arm_scmi/driver.c. > > > > The problem is as follows: > > > > scmi_remove() might return early if info->users is non-zero. The driver > > core however ignores the return value of scmi_remove() and removes the > > device and frees the devm-allocated resources (e.g. *info). > > > > So letting aside that some resources are never freed after a failed call > > of scmi_remove(), the user of the scmi node will probably stumble over > > accessing freed memory soon. I wouldn't be surprised if that was > > exploitable. > > At first, I thought that this was only some kind of mess that needed to > be cleaned up in the remove/exit path but without any real way of being > exposed: this *bad* assumption of mine came from the fact that the SCMI > drivers (like scmi-cpufreq scmi-hwmon) register to use the core SCMI stack > services using an exported symbol (scmi_register_driver) and then, additionally, > each SCMI driver willing to use some the core SCMI protocols issues a > try_module_get (since the protocols could have been modularized) > > So that in a module scenario (with scmi-module being the core platform > driver: > > root@deb-buster-arm64:~# lsmod > Module Size Used by > scmi_hwmon 16384 0 > scmi_module 131072 2 scmi_hwmon > > root@deb-buster-arm64:~# rmmod ./scmi-module.ko > rmmod: ERROR: Module scmi_module is in use by: scmi_hwmon > > BUT, then I realized that all of this refcounting is not going to save me > from an explicitly triggered unbind: > > root@deb-buster-arm64:~# echo 'firmware:scmi' > /sys/bus/platform/drivers/arm-scmi/unbind > [11601.798671] arm-scmi firmware:scmi: remove callback returned a non-zero value. This will be ignored. > > This will indeed expose the issue you reported. > > > I quickly tried to fix this issue, but didn't understand the driver good > > enough. I think a fix would involve adding a get_device() call to > > scmi_handle_get() to prevent scmi_remove() being called while a handle > > exists. > > > > I tried to address the issue with the get_device() calls as you > suggested, but it has really no effect and in fact looking at the code > on the remove path there is nothing that seems to be taken into > consideration to stop a removal (and this indeed is consistent with the > fact that any error returned on the removal/exit path is effectively ignored). Hmm, I thought get_device() would delay calling .remove() but indeed it only delays kobject_release(). > What instead DOES seem to work, it is to add a proper devlink with > device_link_add() declaring any SCMI driver device (like from cpufreq) > as a consumer of the core stack platform device: this will NOT stop the > removal, BUT it does trigger an implicit unbind at first of all the SCMI > drivers currently loaded when an unbind is requested for the core SCMI > platform device: as a consequence the removal can now be triggered > safely by an unbind even if some SCMI driver users are present (they > will be unbound too) Yeah, that should work. Not sure if there is an easier construct. > Now, for this cleanup to fully work, some (long due) rework of the SCMI > core devices handling and removal is needed (and it has partially > already started in other unrelated series), so my plan would be to, at > first, immediately add a '.suppress_bind_attrs = true' to the core driver > to mitigate this (which is also easily portable to stable) and then > rework properly the core SCMI removeal routines to safely re-enable > a proper unbind. (or not re-enabling it if deemed not worth BUT anyway > reworking the core SCMI remove/exit path) > > I'll check my plan with Sudeep, any thoughts from you about this ? > Am I missing something more ? Sure, but nothing I'd be aware of :-) Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ | [-- Attachment #1.2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 176 bytes --] _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-10-13 15:50 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-10-10 8:45 resource leak in firmware/arm_scmi driver Uwe Kleine-König 2022-10-13 11:48 ` Cristian Marussi 2022-10-13 15:49 ` Uwe Kleine-König
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox