Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ata: sata_mv: Cleanup only the initialized ports

When an error occurs in the port initialization loop, currently the
driver tries to cleanup all the ports. This results in a NULL pointer
dereference if the ports were only partially initialized.

Fix this by updating only the number of initialized ports (either
with failure or successfully), before jumping to the error path
and looping over that number in the cleanup loop.

Cc: Andrew Lunn <andrew@lunn.ch>
Reported-by: Mikael Pettersson <mikpelinux@gmail.com>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: stable@vger.kernel.org

authored by

Ezequiel Garcia and committed by
Tejun Heo
8ad116e6 9f9c47f0

+7 -2
+7 -2
drivers/ata/sata_mv.c
··· 4104 4104 if (!hpriv->port_phys) 4105 4105 return -ENOMEM; 4106 4106 host->private_data = hpriv; 4107 - hpriv->n_ports = n_ports; 4108 4107 hpriv->board_idx = chip_soc; 4109 4108 4110 4109 host->iomap = NULL; ··· 4131 4132 hpriv->port_phys[port] = NULL; 4132 4133 if ((rc != -EPROBE_DEFER) && (rc != -ENODEV)) 4133 4134 dev_warn(&pdev->dev, "error getting phy"); 4135 + 4136 + /* Cleanup only the initialized ports */ 4137 + hpriv->n_ports = port; 4134 4138 goto err; 4135 4139 } else 4136 4140 phy_power_on(hpriv->port_phys[port]); 4137 4141 } 4142 + 4143 + /* All the ports have been initialized */ 4144 + hpriv->n_ports = n_ports; 4138 4145 4139 4146 /* 4140 4147 * (Re-)program MBUS remapping windows if we are asked to. ··· 4179 4174 clk_disable_unprepare(hpriv->clk); 4180 4175 clk_put(hpriv->clk); 4181 4176 } 4182 - for (port = 0; port < n_ports; port++) { 4177 + for (port = 0; port < hpriv->n_ports; port++) { 4183 4178 if (!IS_ERR(hpriv->port_clks[port])) { 4184 4179 clk_disable_unprepare(hpriv->port_clks[port]); 4185 4180 clk_put(hpriv->port_clks[port]);