Commit 0546b224 authored by John Keeping's avatar John Keeping Committed by David S. Miller

net: stmmac: dwmac-rk: fix oob read in rk_gmac_setup

KASAN reports an out-of-bounds read in rk_gmac_setup on the line:

	while (ops->regs[i]) {

This happens for most platforms since the regs flexible array member is
empty, so the memory after the ops structure is being read here.  It
seems that mostly this happens to contain zero anyway, so we get lucky
and everything still works.

To avoid adding redundant data to nearly all the ops structures, add a
new flag to indicate whether the regs field is valid and avoid this loop
when it is not.

Fixes: 3bb3d6b1 ("net: stmmac: Add RK3566/RK3568 SoC support")
Signed-off-by: default avatarJohn Keeping <john@metanate.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6209dd77
...@@ -33,6 +33,7 @@ struct rk_gmac_ops { ...@@ -33,6 +33,7 @@ struct rk_gmac_ops {
void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv); void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
bool regs_valid;
u32 regs[]; u32 regs[];
}; };
...@@ -1092,6 +1093,7 @@ static const struct rk_gmac_ops rk3568_ops = { ...@@ -1092,6 +1093,7 @@ static const struct rk_gmac_ops rk3568_ops = {
.set_to_rmii = rk3568_set_to_rmii, .set_to_rmii = rk3568_set_to_rmii,
.set_rgmii_speed = rk3568_set_gmac_speed, .set_rgmii_speed = rk3568_set_gmac_speed,
.set_rmii_speed = rk3568_set_gmac_speed, .set_rmii_speed = rk3568_set_gmac_speed,
.regs_valid = true,
.regs = { .regs = {
0xfe2a0000, /* gmac0 */ 0xfe2a0000, /* gmac0 */
0xfe010000, /* gmac1 */ 0xfe010000, /* gmac1 */
...@@ -1383,7 +1385,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, ...@@ -1383,7 +1385,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
* to be distinguished. * to be distinguished.
*/ */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res) { if (res && ops->regs_valid) {
int i = 0; int i = 0;
while (ops->regs[i]) { while (ops->regs[i]) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment