[PATCH] usb: typec: Prevent memory leak in typec_register_port()
From: Markus Elfring
Date: Fri Jun 28 2024 - 12:14:33 EST
From: Markus Elfring <elfring@xxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 28 Jun 2024 17:46:19 +0200
Memory is allocated for the data structure “typec_port” at the beginning
of this function implementation.
Unfortunately, it was not released in all subsequent error cases.
Thus apply scope-based resource management which became supported
for this programming interface by contributions of Peter Zijlstra
on 2023-05-26.
See also the commit 54da6a0924311c7cf5015533991e44fb8eb12773 ("locking:
Introduce __cleanup() based infrastructure").
* Use the attribute “__free(kfree)” accordingly.
* Reduce the scope for the local variable “port”.
Cc: stable@xxxxxxxxxxxxxxx
Fixes: f31a8702cd36 ("usb: typec: Add retimer handle to port")
Fixes: a7cff92f0635 ("usb: typec: USB Power Delivery helpers for ports and partners")
Fixes: 5c388abefda0 ("usb: typec: fix use after free in typec_register_port()")
Fixes: ad772c39b2fb ("usb: typec: Copy everything from struct typec_capability during registration")
Fixes: cf6e06cddf29 ("usb: typec: Start using ERR_PTR")
Signed-off-by: Markus Elfring <elfring@xxxxxxxxxxxxxxxxxxxxx>
---
I guess that clarifications can become interesting also for backporting concerns
because of the proposed software transformation.
drivers/usb/typec/class.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 9262fcd4144f..97c0afd41e35 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -2372,19 +2372,16 @@ EXPORT_SYMBOL_GPL(typec_port_register_cable_ops);
struct typec_port *typec_register_port(struct device *parent,
const struct typec_capability *cap)
{
- struct typec_port *port;
int ret;
int id;
- port = kzalloc(sizeof(*port), GFP_KERNEL);
+ struct typec_port *port __free(kfree) = kzalloc(sizeof(*port), GFP_KERNEL);
if (!port)
return ERR_PTR(-ENOMEM);
id = ida_alloc(&typec_index_ida, GFP_KERNEL);
- if (id < 0) {
- kfree(port);
+ if (id < 0)
return ERR_PTR(id);
- }
switch (cap->type) {
case TYPEC_PORT_SRC:
@@ -2483,7 +2480,7 @@ struct typec_port *typec_register_port(struct device *parent,
if (ret)
dev_warn(&port->dev, "failed to create symlinks (%d)\n", ret);
- return port;
+ return_ptr(port);
}
EXPORT_SYMBOL_GPL(typec_register_port);
--
2.45.2