lkml.org 
[lkml]   [2020]   [Jun]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.6 042/177] mlxsw: spectrum: Fix use-after-free of split/unsplit/type_set in case reload fails
    Date
    From: Jiri Pirko <jiri@mellanox.com>

    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: 24cc68ad6c46 ("mlxsw: core: Add support for reload")
    Reported-by: Danielle Ratson <danieller@mellanox.com>
    Signed-off-by: Jiri Pirko <jiri@mellanox.com>
    Signed-off-by: Ido Schimmel <idosch@mellanox.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 14 ++++++++++++--
    drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 8 ++++++++
    2 files changed, 20 insertions(+), 2 deletions(-)

    --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
    +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
    @@ -4043,6 +4043,7 @@ static void mlxsw_sp_ports_remove(struct
    mlxsw_sp_port_remove(mlxsw_sp, i);
    mlxsw_sp_cpu_port_remove(mlxsw_sp);
    kfree(mlxsw_sp->ports);
    + mlxsw_sp->ports = NULL;
    }

    static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
    @@ -4079,6 +4080,7 @@ err_port_create:
    mlxsw_sp_cpu_port_remove(mlxsw_sp);
    err_cpu_port_create:
    kfree(mlxsw_sp->ports);
    + mlxsw_sp->ports = NULL;
    return err;
    }

    @@ -4200,6 +4202,14 @@ static int mlxsw_sp_local_ports_offset(s
    return mlxsw_core_res_get(mlxsw_core, local_ports_in_x_res_id);
    }

    +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)
    @@ -4213,7 +4223,7 @@ static int mlxsw_sp_port_split(struct ml
    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);
    @@ -4308,7 +4318,7 @@ static int mlxsw_sp_port_unsplit(struct
    int offset;
    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);
    --- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
    +++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
    @@ -1259,6 +1259,7 @@ static void mlxsw_sx_ports_remove(struct
    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)
    @@ -1293,6 +1294,7 @@ err_port_module_info_get:
    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;
    }

    @@ -1376,6 +1378,12 @@ static int mlxsw_sx_port_type_set(struct
    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;


    \
     
     \ /
      Last update: 2020-06-01 20:40    [W:5.746 / U:0.240 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site