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: Ying Xue <ying.xue@windriver.com> Reviewed-by: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
993b858e37
Коммит
00ede97709
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче