aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShiraz Saleem <shiraz.saleem@intel.com>2017-03-17 19:30:07 -0400
committerDoug Ledford <dledford@redhat.com>2017-03-24 16:23:29 -0400
commit871a8623d3b40221ad1103aff715dfee0aa4dacf (patch)
tree1e3c93fad72ab0f836a785903c7733680fe9c8f8
parent97da3854c526d3a6ee05c849c96e48d21527606c (diff)
i40iw: Receive netdev events post INET_NOTIFIER state
Netdev notification events are de-registered only when all client iwdev instances are removed. If a single client is closed and re-opened, netdev events could arrive even before the Control Queue-Pair (CQP) is created, causing a NULL pointer dereference crash in i40iw_get_cqp_request. Fix this by allowing netdev event notification only after we have reached the INET_NOTIFIER state with respect to device initialization. Reported-by: Stefan Assmann <sassmann@redhat.com> Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com> Reviewed-by: Yuval Shaia <yuval.shaia@oracle.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_utils.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c
index 0f5d43d1f5fc..70c3e9e79508 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_utils.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c
@@ -160,6 +160,9 @@ int i40iw_inetaddr_event(struct notifier_block *notifier,
160 return NOTIFY_DONE; 160 return NOTIFY_DONE;
161 161
162 iwdev = &hdl->device; 162 iwdev = &hdl->device;
163 if (iwdev->init_state < INET_NOTIFIER)
164 return NOTIFY_DONE;
165
163 netdev = iwdev->ldev->netdev; 166 netdev = iwdev->ldev->netdev;
164 upper_dev = netdev_master_upper_dev_get(netdev); 167 upper_dev = netdev_master_upper_dev_get(netdev);
165 if (netdev != event_netdev) 168 if (netdev != event_netdev)
@@ -214,6 +217,9 @@ int i40iw_inet6addr_event(struct notifier_block *notifier,
214 return NOTIFY_DONE; 217 return NOTIFY_DONE;
215 218
216 iwdev = &hdl->device; 219 iwdev = &hdl->device;
220 if (iwdev->init_state < INET_NOTIFIER)
221 return NOTIFY_DONE;
222
217 netdev = iwdev->ldev->netdev; 223 netdev = iwdev->ldev->netdev;
218 if (netdev != event_netdev) 224 if (netdev != event_netdev)
219 return NOTIFY_DONE; 225 return NOTIFY_DONE;
@@ -260,6 +266,8 @@ int i40iw_net_event(struct notifier_block *notifier, unsigned long event, void *
260 if (!iwhdl) 266 if (!iwhdl)
261 return NOTIFY_DONE; 267 return NOTIFY_DONE;
262 iwdev = &iwhdl->device; 268 iwdev = &iwhdl->device;
269 if (iwdev->init_state < INET_NOTIFIER)
270 return NOTIFY_DONE;
263 p = (__be32 *)neigh->primary_key; 271 p = (__be32 *)neigh->primary_key;
264 i40iw_copy_ip_ntohl(local_ipaddr, p); 272 i40iw_copy_ip_ntohl(local_ipaddr, p);
265 if (neigh->nud_state & NUD_VALID) { 273 if (neigh->nud_state & NUD_VALID) {