Commit 00ede977 authored by Ying Xue's avatar Ying Xue Committed by David S. Miller

tipc: protect handler_enabled variable with qitem_lock spin lock

'handler_enabled' is a global flag indicating whether the TIPC
signal handling service is enabled or not. The lack of lock
protection for this flag incurs a risk for contention, so that
a tipc_k_signal() call might queue a signal handler to a destroyed
signal queue, with unpredictable results. To correct this, we let
the already existing 'qitem_lock' protect the flag, as it already
does with the queue itself. This way, we ensure that the flag
always is consistent across all cores.
Signed-off-by: default avatarYing Xue <ying.xue@windriver.com>
Reviewed-by: default avatarPaul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 993b858e
......@@ -56,12 +56,13 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument)
{
struct queue_item *item;
spin_lock_bh(&qitem_lock);
if (!handler_enabled) {
pr_err("Signal request ignored by handler\n");
spin_unlock_bh(&qitem_lock);
return -ENOPROTOOPT;
}
spin_lock_bh(&qitem_lock);
item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC);
if (!item) {
pr_err("Signal queue out of memory\n");
......@@ -112,10 +113,14 @@ void tipc_handler_stop(void)
struct list_head *l, *n;
struct queue_item *item;
if (!handler_enabled)
spin_lock_bh(&qitem_lock);
if (!handler_enabled) {
spin_unlock_bh(&qitem_lock);
return;
}
handler_enabled = 0;
spin_unlock_bh(&qitem_lock);
tasklet_kill(&tipc_tasklet);
spin_lock_bh(&qitem_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment