diff options
author | Shiraz Saleem <shiraz.saleem@intel.com> | 2017-03-17 19:30:07 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2017-03-24 16:23:29 -0400 |
commit | 871a8623d3b40221ad1103aff715dfee0aa4dacf (patch) | |
tree | 1e3c93fad72ab0f836a785903c7733680fe9c8f8 | |
parent | 97da3854c526d3a6ee05c849c96e48d21527606c (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.c | 8 |
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) { |