diff options
author | Jiri Pirko <jiri@mellanox.com> | 2018-02-13 05:22:42 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-02-13 12:22:29 -0500 |
commit | 0f2d2b2736b08dafa3bde31d048750fbc8df3a31 (patch) | |
tree | 82204c267dbe44d87749a3d32f48bd0303da1bb4 | |
parent | d4e9a408ef5de35dd82c1337b9fe48348b70047c (diff) |
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: 76610ebbde18 ("mlxsw: spectrum_router: Refactor virtual router handling")
Fixes: a3d9bc506d64 ("mlxsw: spectrum_router: Extend virtual routers with IPv6 support")
Fixes: d42b0965b1d4 ("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>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index f0b25baba09a..dcc6305f7c22 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | |||
@@ -788,6 +788,9 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp, | |||
788 | u32 tb_id, | 788 | u32 tb_id, |
789 | struct netlink_ext_ack *extack) | 789 | struct netlink_ext_ack *extack) |
790 | { | 790 | { |
791 | struct mlxsw_sp_mr_table *mr4_table; | ||
792 | struct mlxsw_sp_fib *fib4; | ||
793 | struct mlxsw_sp_fib *fib6; | ||
791 | struct mlxsw_sp_vr *vr; | 794 | struct mlxsw_sp_vr *vr; |
792 | int err; | 795 | int err; |
793 | 796 | ||
@@ -796,29 +799,30 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp, | |||
796 | NL_SET_ERR_MSG(extack, "spectrum: Exceeded number of supported virtual routers"); | 799 | NL_SET_ERR_MSG(extack, "spectrum: Exceeded number of supported virtual routers"); |
797 | return ERR_PTR(-EBUSY); | 800 | return ERR_PTR(-EBUSY); |
798 | } | 801 | } |
799 | vr->fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4); | 802 | fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4); |
800 | if (IS_ERR(vr->fib4)) | 803 | if (IS_ERR(fib4)) |
801 | return ERR_CAST(vr->fib4); | 804 | return ERR_CAST(fib4); |
802 | vr->fib6 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6); | 805 | fib6 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6); |
803 | if (IS_ERR(vr->fib6)) { | 806 | if (IS_ERR(fib6)) { |
804 | err = PTR_ERR(vr->fib6); | 807 | err = PTR_ERR(fib6); |
805 | goto err_fib6_create; | 808 | goto err_fib6_create; |
806 | } | 809 | } |
807 | vr->mr4_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id, | 810 | mr4_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id, |
808 | MLXSW_SP_L3_PROTO_IPV4); | 811 | MLXSW_SP_L3_PROTO_IPV4); |
809 | if (IS_ERR(vr->mr4_table)) { | 812 | if (IS_ERR(mr4_table)) { |
810 | err = PTR_ERR(vr->mr4_table); | 813 | err = PTR_ERR(mr4_table); |
811 | goto err_mr_table_create; | 814 | goto err_mr_table_create; |
812 | } | 815 | } |
816 | vr->fib4 = fib4; | ||
817 | vr->fib6 = fib6; | ||
818 | vr->mr4_table = mr4_table; | ||
813 | vr->tb_id = tb_id; | 819 | vr->tb_id = tb_id; |
814 | return vr; | 820 | return vr; |
815 | 821 | ||
816 | err_mr_table_create: | 822 | err_mr_table_create: |
817 | mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib6); | 823 | mlxsw_sp_fib_destroy(mlxsw_sp, fib6); |
818 | vr->fib6 = NULL; | ||
819 | err_fib6_create: | 824 | err_fib6_create: |
820 | mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib4); | 825 | mlxsw_sp_fib_destroy(mlxsw_sp, fib4); |
821 | vr->fib4 = NULL; | ||
822 | return ERR_PTR(err); | 826 | return ERR_PTR(err); |
823 | } | 827 | } |
824 | 828 | ||