s390/ism: Fix locking for forwarding of IRQs and events to clients
authorNiklas Schnelle <schnelle@linux.ibm.com>
Fri, 7 Jul 2023 10:56:20 +0000 (12:56 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 8 Jul 2023 09:07:14 +0000 (10:07 +0100)
commit6b5c13b591d753c6022fbd12f8c0c0a9a07fc065
tree1f89d923e8e47af74636e8e36de2548a655ee130
parentc329b261afe71197d9da83c1f18eb45a7e97e089
s390/ism: Fix locking for forwarding of IRQs and events to clients

The clients array references all registered clients and is protected by
the clients_lock. Besides its use as general list of clients the clients
array is accessed in ism_handle_irq() to forward ISM device events to
clients.

While the clients_lock is taken in the IRQ handler when calling
handle_event() it is however incorrectly not held during the
client->handle_irq() call and for the preceding clients[] access leaving
it unprotected against concurrent client (un-)registration.

Furthermore the accesses to ism->sba_client_arr[] in ism_register_dmb()
and ism_unregister_dmb() are not protected by any lock. This is
especially problematic as the client ID from the ism->sba_client_arr[]
is not checked against NO_CLIENT and neither is the client pointer
checked.

Instead of expanding the use of the clients_lock further add a separate
array in struct ism_dev which references clients subscribed to the
device's events and IRQs. This array is protected by ism->lock which is
already taken in ism_handle_irq() and can be taken outside the IRQ
handler when adding/removing subscribers or the accessing
ism->sba_client_arr[]. This also means that the clients_lock is no
longer taken in IRQ context.

Fixes: 89e7d2ba61b7 ("net/ism: Add new API for client registration")
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/s390/net/ism_drv.c
include/linux/ism.h