diff options
author | Matan Barak <matanb@mellanox.com> | 2013-12-19 14:20:18 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-19 19:04:44 -0500 |
commit | 982290a7fe36e528af292d3e3b61939b1900bfc6 (patch) | |
tree | c8c21acd38576bc0518d79d4784dfc8938327ce0 | |
parent | 0276a330617a0cf380f09e5065299078d3d45886 (diff) |
net/mlx4_core: Check port number for validity before accessing data
Need to validate port number at mlx4_promisc_qp() before use.
Since port number is extracted from gid, as a cooked or corrupted gid
could lead to a crash.
Signed-off-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mcg.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 40594055b831..7c83e6ccc9da 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
@@ -125,9 +125,14 @@ static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
125 | enum mlx4_steer_type steer, | 125 | enum mlx4_steer_type steer, |
126 | u32 qpn) | 126 | u32 qpn) |
127 | { | 127 | { |
128 | struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[port - 1]; | 128 | struct mlx4_steer *s_steer; |
129 | struct mlx4_promisc_qp *pqp; | 129 | struct mlx4_promisc_qp *pqp; |
130 | 130 | ||
131 | if (port < 1 || port > dev->caps.num_ports) | ||
132 | return NULL; | ||
133 | |||
134 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | ||
135 | |||
131 | list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { | 136 | list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { |
132 | if (pqp->qpn == qpn) | 137 | if (pqp->qpn == qpn) |
133 | return pqp; | 138 | return pqp; |
@@ -154,6 +159,9 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port, | |||
154 | u32 prot; | 159 | u32 prot; |
155 | int err; | 160 | int err; |
156 | 161 | ||
162 | if (port < 1 || port > dev->caps.num_ports) | ||
163 | return -EINVAL; | ||
164 | |||
157 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 165 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
158 | new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL); | 166 | new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL); |
159 | if (!new_entry) | 167 | if (!new_entry) |
@@ -238,6 +246,9 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port, | |||
238 | struct mlx4_promisc_qp *pqp; | 246 | struct mlx4_promisc_qp *pqp; |
239 | struct mlx4_promisc_qp *dqp; | 247 | struct mlx4_promisc_qp *dqp; |
240 | 248 | ||
249 | if (port < 1 || port > dev->caps.num_ports) | ||
250 | return -EINVAL; | ||
251 | |||
241 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 252 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
242 | 253 | ||
243 | pqp = get_promisc_qp(dev, port, steer, qpn); | 254 | pqp = get_promisc_qp(dev, port, steer, qpn); |
@@ -283,6 +294,9 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port, | |||
283 | struct mlx4_steer_index *tmp_entry, *entry = NULL; | 294 | struct mlx4_steer_index *tmp_entry, *entry = NULL; |
284 | struct mlx4_promisc_qp *dqp, *tmp_dqp; | 295 | struct mlx4_promisc_qp *dqp, *tmp_dqp; |
285 | 296 | ||
297 | if (port < 1 || port > dev->caps.num_ports) | ||
298 | return NULL; | ||
299 | |||
286 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 300 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
287 | 301 | ||
288 | /* if qp is not promisc, it cannot be duplicated */ | 302 | /* if qp is not promisc, it cannot be duplicated */ |
@@ -324,6 +338,9 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port, | |||
324 | bool ret = false; | 338 | bool ret = false; |
325 | int i; | 339 | int i; |
326 | 340 | ||
341 | if (port < 1 || port > dev->caps.num_ports) | ||
342 | return NULL; | ||
343 | |||
327 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 344 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
328 | 345 | ||
329 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 346 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
@@ -378,6 +395,9 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
378 | int err; | 395 | int err; |
379 | struct mlx4_priv *priv = mlx4_priv(dev); | 396 | struct mlx4_priv *priv = mlx4_priv(dev); |
380 | 397 | ||
398 | if (port < 1 || port > dev->caps.num_ports) | ||
399 | return -EINVAL; | ||
400 | |||
381 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 401 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
382 | 402 | ||
383 | mutex_lock(&priv->mcg_table.mutex); | 403 | mutex_lock(&priv->mcg_table.mutex); |
@@ -484,6 +504,9 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
484 | int loc, i; | 504 | int loc, i; |
485 | int err; | 505 | int err; |
486 | 506 | ||
507 | if (port < 1 || port > dev->caps.num_ports) | ||
508 | return -EINVAL; | ||
509 | |||
487 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 510 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
488 | mutex_lock(&priv->mcg_table.mutex); | 511 | mutex_lock(&priv->mcg_table.mutex); |
489 | 512 | ||
@@ -910,6 +933,9 @@ int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], | |||
910 | u8 port = gid[5]; | 933 | u8 port = gid[5]; |
911 | u8 new_entry = 0; | 934 | u8 new_entry = 0; |
912 | 935 | ||
936 | if (port < 1 || port > dev->caps.num_ports) | ||
937 | return -EINVAL; | ||
938 | |||
913 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 939 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
914 | if (IS_ERR(mailbox)) | 940 | if (IS_ERR(mailbox)) |
915 | return PTR_ERR(mailbox); | 941 | return PTR_ERR(mailbox); |