Skip to content

Commit

Permalink
mlxsw: spectrum: Fix use-after-free of split/unsplit/type_set in case…
Browse files Browse the repository at this point in the history
… reload fails

commit 4340f42f207eacb81e7a6b6bb1e3b6afad9a2e26 upstream.

In case of reload fail, the mlxsw_sp->ports contains a pointer to a
freed memory (either by reload_down() or reload_up() error path).
Fix this by initializing the pointer to NULL and checking it before
dereferencing in split/unsplit/type_set callpaths.

Fixes: 24cc68a ("mlxsw: core: Add support for reload")
Reported-by: Danielle Ratson <[email protected]>
Signed-off-by: Jiri Pirko <[email protected]>
Signed-off-by: Ido Schimmel <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
jpirko authored and gregkh committed Jun 3, 2020
1 parent ec3150f commit 78c8a06
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
14 changes: 12 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -3126,6 +3126,7 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
mlxsw_sp_port_remove(mlxsw_sp, i);
kfree(mlxsw_sp->port_to_module);
kfree(mlxsw_sp->ports);
mlxsw_sp->ports = NULL;
}

static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
Expand Down Expand Up @@ -3174,6 +3175,7 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
kfree(mlxsw_sp->port_to_module);
err_port_to_module_alloc:
kfree(mlxsw_sp->ports);
mlxsw_sp->ports = NULL;
return err;
}

Expand Down Expand Up @@ -3228,6 +3230,14 @@ static void mlxsw_sp_port_unsplit_create(struct mlxsw_sp *mlxsw_sp,
}
}

static struct mlxsw_sp_port *
mlxsw_sp_port_get_by_local_port(struct mlxsw_sp *mlxsw_sp, u8 local_port)
{
if (mlxsw_sp->ports && mlxsw_sp->ports[local_port])
return mlxsw_sp->ports[local_port];
return NULL;
}

static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
unsigned int count,
struct netlink_ext_ack *extack)
Expand All @@ -3238,7 +3248,7 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
int i;
int err;

mlxsw_sp_port = mlxsw_sp->ports[local_port];
mlxsw_sp_port = mlxsw_sp_port_get_by_local_port(mlxsw_sp, local_port);
if (!mlxsw_sp_port) {
dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
local_port);
Expand Down Expand Up @@ -3305,7 +3315,7 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port,
unsigned int count;
int i;

mlxsw_sp_port = mlxsw_sp->ports[local_port];
mlxsw_sp_port = mlxsw_sp_port_get_by_local_port(mlxsw_sp, local_port);
if (!mlxsw_sp_port) {
dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
local_port);
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/switchx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,7 @@ static void mlxsw_sx_ports_remove(struct mlxsw_sx *mlxsw_sx)
if (mlxsw_sx_port_created(mlxsw_sx, i))
mlxsw_sx_port_remove(mlxsw_sx, i);
kfree(mlxsw_sx->ports);
mlxsw_sx->ports = NULL;
}

static int mlxsw_sx_ports_create(struct mlxsw_sx *mlxsw_sx)
Expand Down Expand Up @@ -1323,6 +1324,7 @@ static int mlxsw_sx_ports_create(struct mlxsw_sx *mlxsw_sx)
if (mlxsw_sx_port_created(mlxsw_sx, i))
mlxsw_sx_port_remove(mlxsw_sx, i);
kfree(mlxsw_sx->ports);
mlxsw_sx->ports = NULL;
return err;
}

Expand Down Expand Up @@ -1406,6 +1408,12 @@ static int mlxsw_sx_port_type_set(struct mlxsw_core *mlxsw_core, u8 local_port,
u8 module, width;
int err;

if (!mlxsw_sx->ports || !mlxsw_sx->ports[local_port]) {
dev_err(mlxsw_sx->bus_info->dev, "Port number \"%d\" does not exist\n",
local_port);
return -EINVAL;
}

if (new_type == DEVLINK_PORT_TYPE_AUTO)
return -EOPNOTSUPP;

Expand Down

0 comments on commit 78c8a06

Please sign in to comment.