clk: clk-loongson2: Fix memory corruption bug in struct loongson2_clk_provider
Subsystems (2)
PATCH 1/1 clk: clk-loongson2: Fix memory corruption bug in struct loongson2_clk_provider
Some heap space is allocated for the flexible structure struct clk_hw_onecell_data and its flexible-array member hws through the composite structure struct loongson2_clk_provider in function loongson2_clk_probe(), as shown below:
289 struct loongson2_clk_provider *clp; ...
296 for (p = data; p->name; p++)
297 clks_num++;
298
299 clp = devm_kzalloc(dev, struct_size(clp, clk_data.hws, clks_num),
300 GFP_KERNEL);
Then some data is written into the flexible array:
350 clp->clk_data.hws[p->id] = hw;
This corrupts clk_lock, which is the spinlock variable immediately following the clk_data member in struct loongson2_clk_provider:
struct loongson2_clk_provider {
void __iomem *base;
struct device *dev;
struct clk_hw_onecell_data clk_data;
spinlock_t clk_lock; /* protect access to DIV registers */
};The problem is that the flexible structure is currently placed in the middle of struct loongson2_clk_provider instead of at the end.
Fix this by moving struct clk_hw_onecell_data clk_data; to the end of struct loongson2_clk_provider. Also, add a code comment to help prevent this from happening again in case new members are added to the structure in the future.
This change also fixes the following -Wflex-array-member-not-at-end warning:
drivers/clk/clk-loongson2.c:32:36: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
--- drivers/clk/clk-loongson2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/clk/clk-loongson2.c +3 -1
@@ -29,8 +29,10 @@ enum loongson2_clk_type {struct loongson2_clk_provider {void __iomem *base;struct device *dev; -struct clk_hw_onecell_data clk_data;spinlock_t clk_lock;/* protect access to DIV registers */ + +/* Must be last --ends in a flexible-array member. */ +struct clk_hw_onecell_data clk_data; };struct loongson2_clk_data {
Signature · 1 line
2.43.0
Quoting Gustavo A. R. Silva (2024-11-14 14:49:21)
Quoted 38 lines
Some heap space is allocated for the flexible structure
struct clk_hw_onecell_dataand its flexible-array memberhwsthrough the composite structurestruct loongson2_clk_providerin functionloongson2_clk_probe(), as shown below:289 struct loongson2_clk_provider *clp; ...296 for (p = data;
p->name; p++)
297 clks_num++;
298
299 clp = devm_kzalloc(dev,struct_size(clp, clk_data.hws, clks_num),
300GFP_KERNEL);Then some data is written into the flexible array:
350 clp->clk_data.hws[p->id] = hw;
This corrupts
clk_lock, which is the spinlock variable immediately following theclk_datamember instruct loongson2_clk_provider:struct loongson2_clk_provider { void __iomem *base; struct device *dev; struct clk_hw_onecell_data clk_data; spinlock_t clk_lock; /* protect access to DIV registers */ };The problem is that the flexible structure is currently placed in the middle of
struct loongson2_clk_providerinstead of at the end.Fix this by moving
struct clk_hw_onecell_data clk_data;to the end ofstruct loongson2_clk_provider. Also, add a code comment to help prevent this from happening again in case new members are added to the structure in the future.This change also fixes the following -Wflex-array-member-not-at-end warning:
Quoted 6 lines
drivers/clk/clk-loongson2.c:32:36: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]Fixes 9796ec0bd04b ("clk: clk-loongson2: Refactor driver for adding new platforms")Signed-off-by Gustavo A. R. Silva <[email protected]>---
Applied to clk-next