Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -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);