mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-24 13:13:57 +08:00
mlxsw: spectrum_router: Fix error path in mlxsw_sp_vr_create
Since mlxsw_sp_fib_create() and mlxsw_sp_mr_table_create() use ERR_PTR macro to propagate int err through return of a pointer, the return value is not NULL in case of failure. So if one of the calls fails, one of vr->fib4, vr->fib6 or vr->mr4_table is not NULL and mlxsw_sp_vr_is_used wrongly assumes that vr is in use which leads to crash like following one: [ 1293.949291] BUG: unable to handle kernel NULL pointer dereference at 00000000000006c9 [ 1293.952729] IP: mlxsw_sp_mr_table_flush+0x15/0x70 [mlxsw_spectrum] Fix this by using local variables to hold the pointers and set vr->* only in case everything went fine. Fixes:76610ebbde
("mlxsw: spectrum_router: Refactor virtual router handling") Fixes:a3d9bc506d
("mlxsw: spectrum_router: Extend virtual routers with IPv6 support") Fixes:d42b0965b1
("mlxsw: spectrum_router: Add multicast routes notification handling functionality") Signed-off-by: Jiri Pirko <jiri@mellanox.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d4e9a408ef
commit
0f2d2b2736
@ -788,6 +788,9 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp,
|
||||
u32 tb_id,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mlxsw_sp_mr_table *mr4_table;
|
||||
struct mlxsw_sp_fib *fib4;
|
||||
struct mlxsw_sp_fib *fib6;
|
||||
struct mlxsw_sp_vr *vr;
|
||||
int err;
|
||||
|
||||
@ -796,29 +799,30 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp,
|
||||
NL_SET_ERR_MSG(extack, "spectrum: Exceeded number of supported virtual routers");
|
||||
return ERR_PTR(-EBUSY);
|
||||
}
|
||||
vr->fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4);
|
||||
if (IS_ERR(vr->fib4))
|
||||
return ERR_CAST(vr->fib4);
|
||||
vr->fib6 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6);
|
||||
if (IS_ERR(vr->fib6)) {
|
||||
err = PTR_ERR(vr->fib6);
|
||||
fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4);
|
||||
if (IS_ERR(fib4))
|
||||
return ERR_CAST(fib4);
|
||||
fib6 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6);
|
||||
if (IS_ERR(fib6)) {
|
||||
err = PTR_ERR(fib6);
|
||||
goto err_fib6_create;
|
||||
}
|
||||
vr->mr4_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id,
|
||||
MLXSW_SP_L3_PROTO_IPV4);
|
||||
if (IS_ERR(vr->mr4_table)) {
|
||||
err = PTR_ERR(vr->mr4_table);
|
||||
mr4_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id,
|
||||
MLXSW_SP_L3_PROTO_IPV4);
|
||||
if (IS_ERR(mr4_table)) {
|
||||
err = PTR_ERR(mr4_table);
|
||||
goto err_mr_table_create;
|
||||
}
|
||||
vr->fib4 = fib4;
|
||||
vr->fib6 = fib6;
|
||||
vr->mr4_table = mr4_table;
|
||||
vr->tb_id = tb_id;
|
||||
return vr;
|
||||
|
||||
err_mr_table_create:
|
||||
mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib6);
|
||||
vr->fib6 = NULL;
|
||||
mlxsw_sp_fib_destroy(mlxsw_sp, fib6);
|
||||
err_fib6_create:
|
||||
mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib4);
|
||||
vr->fib4 = NULL;
|
||||
mlxsw_sp_fib_destroy(mlxsw_sp, fib4);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user