lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Sun, 19 Jul 2020 07:33:24 -0700 From: trix@...hat.com To: marek.vasut@...il.com, mturquette@...libre.com, sboyd@...nel.org, aford173@...il.com Cc: linux-clk@...r.kernel.org, linux-kernel@...r.kernel.org, Tom Rix <trix@...hat.com> Subject: [PATCH] clk: vc5: Fix use after free in vc5_probe From: Tom Rix <trix@...hat.com> clang static analysis reports this error clk-versaclock5.c:887:3: warning: Use of memory after it is freed [unix.Malloc] dev_err(&client->dev, "unable to register %s\n", init.name); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A representative problem block of code is ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux); kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); goto err_clk; } init.name is freed and then used. So reorder the free. Fixes: f491276a5168 ("clk: vc5: Allow Versaclock driver to support multiple instances") Signed-off-by: Tom Rix <trix@...hat.com> --- drivers/clk/clk-versaclock5.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index 9a5fb3834b9a..72c9ae460a01 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -882,11 +882,12 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) init.parent_names = parent_names; vc5->clk_mux.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux); - kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); + kfree(init.name); goto err_clk; } + kfree(init.name); /* clock framework made a copy of the name */ if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) { /* Register frequency doubler */ @@ -900,12 +901,13 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) init.num_parents = 1; vc5->clk_mul.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul); - kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); + kfree(init.name); goto err_clk; } + kfree(init.name); /* clock framework made a copy of the name */ } /* Register PFD */ @@ -921,11 +923,12 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) init.num_parents = 1; vc5->clk_pfd.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd); - kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); + kfree(init.name); goto err_clk; } + kfree(init.name); /* clock framework made a copy of the name */ /* Register PLL */ memset(&init, 0, sizeof(init)); @@ -939,11 +942,12 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) vc5->clk_pll.vc5 = vc5; vc5->clk_pll.hw.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw); - kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); + kfree(init.name); goto err_clk; } + kfree(init.name); /* clock framework made a copy of the name */ /* Register FODs */ for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) { @@ -960,12 +964,13 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) vc5->clk_fod[n].vc5 = vc5; vc5->clk_fod[n].hw.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw); - kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); + kfree(init.name); goto err_clk; } + kfree(init.name); /* clock framework made a copy of the name */ } /* Register MUX-connected OUT0_I2C_SELB output */ @@ -981,11 +986,12 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) vc5->clk_out[0].vc5 = vc5; vc5->clk_out[0].hw.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw); - kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); + kfree(init.name); goto err_clk; } + kfree(init.name); /* clock framework made a copy of the name */ /* Register FOD-connected OUTx outputs */ for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) { @@ -1008,12 +1014,13 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) vc5->clk_out[n].vc5 = vc5; vc5->clk_out[n].hw.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[n].hw); - kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); + kfree(init.name); goto err_clk; } + kfree(init.name); /* clock framework made a copy of the name */ /* Fetch Clock Output configuration from DT (if specified) */ ret = vc5_get_output_config(client, &vc5->clk_out[n]); -- 2.18.1
Powered by blists - more mailing lists