[PATCH 1/8] cyclic: Prevent corruption of cyclic list on reassignment
Marek Vasut
marek.vasut+renesas at mailbox.org
Sat Jan 18 05:00:55 CET 2025
Make cyclic_register() return error code, 0 in case of success,
-EALREADY in case the called attempts to re-register already
registered struct cyclic_info. The re-registration would lead
to corruption of gd->cyclic_list because the re-registration
would memset() one of its nodes, prevent that. Unregister only
initialized struct cyclic_info.
Signed-off-by: Marek Vasut <marek.vasut+renesas at mailbox.org>
---
Cc: Aaron Williams <awilliams at marvell.com>
Cc: Anatolij Gustschin <agust at denx.de>
Cc: Angelo Dureghello <angelo at kernel-space.org>
Cc: Christian Marangi <ansuelsmth at gmail.com>
Cc: Devarsh Thakkar <devarsht at ti.com>
Cc: Heinrich Schuchardt <xypron.glpk at gmx.de>
Cc: Jaehoon Chung <jh80.chung at samsung.com>
Cc: Michael Polyntsov <michael.polyntsov at iopsys.eu>
Cc: Michael Trimarchi <michael at amarulasolutions.com>
Cc: Nikhil M Jain <n-jain1 at ti.com>
Cc: Peng Fan <peng.fan at nxp.com>
Cc: Peter Robinson <pbrobinson at gmail.com>
Cc: Rasmus Villemoes <rasmus.villemoes at prevas.dk>
Cc: Ronald Wahl <ronald.wahl at legrand.com>
Cc: Simon Glass <sjg at chromium.org>
Cc: Stefan Roese <sr at denx.de>
Cc: Tim Harvey <tharvey at gateworks.com>
Cc: Tom Rini <trini at konsulko.com>
Cc: u-boot at lists.denx.de
---
common/cyclic.c | 14 +++++++++++---
include/cyclic.h | 9 ++++++---
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/common/cyclic.c b/common/cyclic.c
index 196797fd61e..53156a704cc 100644
--- a/common/cyclic.c
+++ b/common/cyclic.c
@@ -27,9 +27,13 @@ struct hlist_head *cyclic_get_list(void)
return (struct hlist_head *)&gd->cyclic_list;
}
-void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func,
- uint64_t delay_us, const char *name)
+int cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func,
+ uint64_t delay_us, const char *name)
{
+ /* Reassignment of function would corrupt cyclic list, exit */
+ if (cyclic->func)
+ return -EALREADY;
+
memset(cyclic, 0, sizeof(*cyclic));
/* Store values in struct */
@@ -38,11 +42,15 @@ void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func,
cyclic->delay_us = delay_us;
cyclic->start_time_us = timer_get_us();
hlist_add_head(&cyclic->list, cyclic_get_list());
+
+ return 0;
}
void cyclic_unregister(struct cyclic_info *cyclic)
{
- hlist_del(&cyclic->list);
+ /* Unregister only initialized struct cyclic_info */
+ if (cyclic->func)
+ hlist_del(&cyclic->list);
}
static void cyclic_run(void)
diff --git a/include/cyclic.h b/include/cyclic.h
index c6c463d68e9..c86ac407332 100644
--- a/include/cyclic.h
+++ b/include/cyclic.h
@@ -60,8 +60,10 @@ typedef void (*cyclic_func_t)(struct cyclic_info *c);
* The function @func will be called with @cyclic as its
* argument. @cyclic will usually be embedded in some device-specific
* structure, which the callback can retrieve using container_of().
+ *
+ * @return 0 on success, -EALREADY on repeated registration, -ve otherwise
*/
-void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func,
+int cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func,
uint64_t delay_us, const char *name);
/**
@@ -89,9 +91,10 @@ struct hlist_head *cyclic_get_list(void);
#else
-static inline void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func,
- uint64_t delay_us, const char *name)
+static inline int cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func,
+ uint64_t delay_us, const char *name)
{
+ return 0;
}
static inline void cyclic_unregister(struct cyclic_info *cyclic)
--
2.45.2
More information about the U-Boot
mailing list