• Oleg Nesterov's avatar
    sigqueue_free: fix the race with collect_signal() · 60187d27
    Oleg Nesterov authored
    Spotted by taoyue <yue.tao@windriver.com> and Jeremy Katz <jeremy.katz@windriver.com>.
    
    collect_signal:				sigqueue_free:
    
    	list_del_init(&first->list);
    						if (!list_empty(&q->list)) {
    							// not taken
    						}
    						q->flags &= ~SIGQUEUE_PREALLOC;
    
    	__sigqueue_free(first);			__sigqueue_free(q);
    
    Now, __sigqueue_free() is called twice on the same "struct sigqueue" with the
    obviously bad implications.
    
    In particular, this double free breaks the array_cache->avail logic, so the
    same sigqueue could be "allocated" twice, and the bug can manifest itself via
    the "impossible" BUG_ON(!SIGQUEUE_PREALLOC) in sigqueue_free/send_sigqueue.
    
    Hopefully this can explain these mysterious bug-reports, see
    
    	http://marc.info/?t=118766926500003
    	http://marc.info/?t=118466273000005
    
    Alexey Dobriyan reports this patch makes the difference for the testcase, but
    nobody has an access to the application which opened the problems originally.
    
    Also, this patch removes tasklist lock/unlock, ->siglock is enough.
    Signed-off-by: default avatarOleg Nesterov <oleg@tv-sign.ru>
    Cc: taoyue <yue.tao@windriver.com>
    Cc: Jeremy Katz <jeremy.katz@windriver.com>
    Cc: Sukadev Bhattiprolu <sukadev@us.ibm.com>
    Cc: Alexey Dobriyan <adobriyan@sw.ru>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Roland McGrath <roland@redhat.com>
    Cc: <stable@kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    60187d27
signal.c 64.6 KB