Skip to content

Commit 8200597

Browse files
Colin Ian Kingbebarino
authored andcommitted
clk: vc5: fix use of memory after it has been kfree'd
There are a several places where printing an error message of init.name occurs after init.name has been kfree'd. Also the failure message is duplicated each time in the code. Fix this by adding a registration error failure path for these cases, moving the duplicated error messages to one common point and kfree'ing init.name only after it has been used. Changes also shrink the object code size by 171 bytes (x86-64, gcc 9.3): Before: text data bss dec hex filename 21057 3960 64 25081 61f9 drivers/clk/clk-versaclock5.o After: text data bss dec hex filename 20886 3960 64 24910 614e drivers/clk/clk-versaclock5.o Addresses-Coverity: ("Use after free") Fixes: f491276 ("clk: vc5: Allow Versaclock driver to support multiple instances") Signed-off-by: Colin Ian King <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Luca Ceresoli <[email protected]> [[email protected]: Drop stray newline] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 260249f commit 8200597

File tree

1 file changed

+18
-32
lines changed

1 file changed

+18
-32
lines changed

drivers/clk/clk-versaclock5.c

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -882,11 +882,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
882882
init.parent_names = parent_names;
883883
vc5->clk_mux.init = &init;
884884
ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux);
885+
if (ret)
886+
goto err_clk_register;
885887
kfree(init.name); /* clock framework made a copy of the name */
886-
if (ret) {
887-
dev_err(&client->dev, "unable to register %s\n", init.name);
888-
goto err_clk;
889-
}
890888

891889
if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) {
892890
/* Register frequency doubler */
@@ -900,12 +898,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
900898
init.num_parents = 1;
901899
vc5->clk_mul.init = &init;
902900
ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul);
901+
if (ret)
902+
goto err_clk_register;
903903
kfree(init.name); /* clock framework made a copy of the name */
904-
if (ret) {
905-
dev_err(&client->dev, "unable to register %s\n",
906-
init.name);
907-
goto err_clk;
908-
}
909904
}
910905

911906
/* Register PFD */
@@ -921,11 +916,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
921916
init.num_parents = 1;
922917
vc5->clk_pfd.init = &init;
923918
ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd);
919+
if (ret)
920+
goto err_clk_register;
924921
kfree(init.name); /* clock framework made a copy of the name */
925-
if (ret) {
926-
dev_err(&client->dev, "unable to register %s\n", init.name);
927-
goto err_clk;
928-
}
929922

930923
/* Register PLL */
931924
memset(&init, 0, sizeof(init));
@@ -939,11 +932,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
939932
vc5->clk_pll.vc5 = vc5;
940933
vc5->clk_pll.hw.init = &init;
941934
ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw);
935+
if (ret)
936+
goto err_clk_register;
942937
kfree(init.name); /* clock framework made a copy of the name */
943-
if (ret) {
944-
dev_err(&client->dev, "unable to register %s\n", init.name);
945-
goto err_clk;
946-
}
947938

948939
/* Register FODs */
949940
for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) {
@@ -960,12 +951,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
960951
vc5->clk_fod[n].vc5 = vc5;
961952
vc5->clk_fod[n].hw.init = &init;
962953
ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw);
954+
if (ret)
955+
goto err_clk_register;
963956
kfree(init.name); /* clock framework made a copy of the name */
964-
if (ret) {
965-
dev_err(&client->dev, "unable to register %s\n",
966-
init.name);
967-
goto err_clk;
968-
}
969957
}
970958

971959
/* Register MUX-connected OUT0_I2C_SELB output */
@@ -981,11 +969,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
981969
vc5->clk_out[0].vc5 = vc5;
982970
vc5->clk_out[0].hw.init = &init;
983971
ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw);
984-
kfree(init.name); /* clock framework made a copy of the name */
985-
if (ret) {
986-
dev_err(&client->dev, "unable to register %s\n", init.name);
987-
goto err_clk;
988-
}
972+
if (ret)
973+
goto err_clk_register;
974+
kfree(init.name); /* clock framework made a copy of the name */
989975

990976
/* Register FOD-connected OUTx outputs */
991977
for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) {
@@ -1008,12 +994,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
1008994
vc5->clk_out[n].vc5 = vc5;
1009995
vc5->clk_out[n].hw.init = &init;
1010996
ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[n].hw);
997+
if (ret)
998+
goto err_clk_register;
1011999
kfree(init.name); /* clock framework made a copy of the name */
1012-
if (ret) {
1013-
dev_err(&client->dev, "unable to register %s\n",
1014-
init.name);
1015-
goto err_clk;
1016-
}
10171000

10181001
/* Fetch Clock Output configuration from DT (if specified) */
10191002
ret = vc5_get_output_config(client, &vc5->clk_out[n]);
@@ -1029,6 +1012,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
10291012

10301013
return 0;
10311014

1015+
err_clk_register:
1016+
dev_err(&client->dev, "unable to register %s\n", init.name);
1017+
kfree(init.name); /* clock framework made a copy of the name */
10321018
err_clk:
10331019
if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
10341020
clk_unregister_fixed_rate(vc5->pin_xin);

0 commit comments

Comments
 (0)