提交 0f2d2b27 编写于 作者: J Jiri Pirko 提交者: David S. Miller

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: 76610ebb ("mlxsw: spectrum_router: Refactor virtual router handling")
Fixes: a3d9bc50 ("mlxsw: spectrum_router: Extend virtual routers with IPv6 support")
Fixes: d42b0965 ("mlxsw: spectrum_router: Add multicast routes notification handling functionality")
Signed-off-by: NJiri Pirko <jiri@mellanox.com>
Reviewed-by: NIdo Schimmel <idosch@mellanox.com>
Signed-off-by: NJiri Pirko <jiri@mellanox.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 d4e9a408
...@@ -788,6 +788,9 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp, ...@@ -788,6 +788,9 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp,
u32 tb_id, u32 tb_id,
struct netlink_ext_ack *extack) 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; struct mlxsw_sp_vr *vr;
int err; int err;
...@@ -796,29 +799,30 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp, ...@@ -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"); NL_SET_ERR_MSG(extack, "spectrum: Exceeded number of supported virtual routers");
return ERR_PTR(-EBUSY); return ERR_PTR(-EBUSY);
} }
vr->fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4); fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4);
if (IS_ERR(vr->fib4)) if (IS_ERR(fib4))
return ERR_CAST(vr->fib4); return ERR_CAST(fib4);
vr->fib6 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6); fib6 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6);
if (IS_ERR(vr->fib6)) { if (IS_ERR(fib6)) {
err = PTR_ERR(vr->fib6); err = PTR_ERR(fib6);
goto err_fib6_create; goto err_fib6_create;
} }
vr->mr4_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id, mr4_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id,
MLXSW_SP_L3_PROTO_IPV4); MLXSW_SP_L3_PROTO_IPV4);
if (IS_ERR(vr->mr4_table)) { if (IS_ERR(mr4_table)) {
err = PTR_ERR(vr->mr4_table); err = PTR_ERR(mr4_table);
goto err_mr_table_create; goto err_mr_table_create;
} }
vr->fib4 = fib4;
vr->fib6 = fib6;
vr->mr4_table = mr4_table;
vr->tb_id = tb_id; vr->tb_id = tb_id;
return vr; return vr;
err_mr_table_create: err_mr_table_create:
mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib6); mlxsw_sp_fib_destroy(mlxsw_sp, fib6);
vr->fib6 = NULL;
err_fib6_create: err_fib6_create:
mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib4); mlxsw_sp_fib_destroy(mlxsw_sp, fib4);
vr->fib4 = NULL;
return ERR_PTR(err); return ERR_PTR(err);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册