| From foo@baz Thu Dec 21 09:02:40 CET 2017 |
| From: Shiraz Saleem <shiraz.saleem@intel.com> |
| Date: Fri, 17 Mar 2017 18:30:07 -0500 |
| Subject: i40iw: Receive netdev events post INET_NOTIFIER state |
| |
| From: Shiraz Saleem <shiraz.saleem@intel.com> |
| |
| |
| [ Upstream commit 871a8623d3b40221ad1103aff715dfee0aa4dacf ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <alexander.levin@verizon.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/infiniband/hw/i40iw/i40iw_utils.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| --- a/drivers/infiniband/hw/i40iw/i40iw_utils.c |
| +++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c |
| @@ -159,6 +159,9 @@ int i40iw_inetaddr_event(struct notifier |
| return NOTIFY_DONE; |
| |
| iwdev = &hdl->device; |
| + if (iwdev->init_state < INET_NOTIFIER) |
| + return NOTIFY_DONE; |
| + |
| netdev = iwdev->ldev->netdev; |
| upper_dev = netdev_master_upper_dev_get(netdev); |
| if (netdev != event_netdev) |
| @@ -231,6 +234,9 @@ int i40iw_inet6addr_event(struct notifie |
| return NOTIFY_DONE; |
| |
| iwdev = &hdl->device; |
| + if (iwdev->init_state < INET_NOTIFIER) |
| + return NOTIFY_DONE; |
| + |
| netdev = iwdev->ldev->netdev; |
| if (netdev != event_netdev) |
| return NOTIFY_DONE; |
| @@ -280,6 +286,8 @@ int i40iw_net_event(struct notifier_bloc |
| if (!iwhdl) |
| return NOTIFY_DONE; |
| iwdev = &iwhdl->device; |
| + if (iwdev->init_state < INET_NOTIFIER) |
| + return NOTIFY_DONE; |
| p = (__be32 *)neigh->primary_key; |
| i40iw_copy_ip_ntohl(local_ipaddr, p); |
| if (neigh->nud_state & NUD_VALID) { |