Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932126AbWCMIwU (ORCPT ); Mon, 13 Mar 2006 03:52:20 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S932364AbWCMIwT (ORCPT ); Mon, 13 Mar 2006 03:52:19 -0500 Received: from omega.webmasters.gr.jp ([218.44.239.78]:58282 "EHLO webmasters.gr.jp") by vger.kernel.org with ESMTP id S932126AbWCMIwT (ORCPT ); Mon, 13 Mar 2006 03:52:19 -0500 Date: Mon, 13 Mar 2006 17:52:05 +0900 Message-ID: <81ek16loay.wl%gotom@sanori.org> From: GOTO Masanori To: akpm@osdl.org, linux-kernel@vger.kernel.org Cc: gotom@sanori.org Subject: [PATCH] Fix sigaltstack corruption among cloned threads User-Agent: Wanderlust/2.11.30 (Wonderwall) SEMI/1.14.6 (Maruoka) FLIM/1.14.6 (Marutamachi) APEL/10.6 Emacs/21.4 (i386-pc-linux-gnu) MULE/5.0 (SAKAKI) MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2385 Lines: 51 This patch fixes alternate signal stack corruption among cloned threads with CLONE_SIGHAND (and CLONE_VM) for linux-2.6.16-rc6. The value of alternate signal stack is currently inherited after a call of clone(... CLONE_SIGHAND | CLONE_VM). But if sigaltstack is set by a parent thread, and then if multiple cloned child threads (+ parent threads) call signal handler at the same time, some threads may be conflicted - because they share to use the same alternative signal stack region. Finally they get sigsegv. It's an undesirable race condition. Note that child threads created from NPTL pthread_create() also hit this conflict when the parent thread uses sigaltstack, without my patch. To fix this problem, this patch clears the child threads' sigaltstack information like exec(). This behavior follows the SUSv3 specification. In SUSv3, pthread_create() says "The alternate stack shall not be inherited (when new threads are initialized)". It means that sigaltstack should be cleared when sigaltstack memory space is shared by cloned threads with CLONE_SIGHAND. Note that I chose "if (clone_flags & CLONE_SIGHAND)" line because: - If clone_flags line is not existed, fork() does not inherit sigaltstack. - CLONE_VM is another choice, but vfork() does not inherit sigaltstack. - CLONE_SIGHAND implies CLONE_VM, and it looks suitable. - CLONE_THREAD is another candidate, and includes CLONE_SIGHAND + CLONE_VM, but this flag has a bit different semantics. I decided to use CLONE_SIGHAND. -- gotom Signed-Off-By: GOTO Masanori --- linux-2.6.16-rc6.gotom/kernel/fork.c 2006-03-13 14:45:50.686049000 +0900 +++ linux-2.6.16-rc6/kernel/fork.c 2006-03-13 14:47:24.162839240 +0900 @@ -1062,6 +1062,13 @@ static task_t *copy_process(unsigned lon p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL; /* + * sigaltstack should be cleared when CLONE_SIGHAND (and CLONE_VM) is + * specified. + */ + if (clone_flags & CLONE_SIGHAND) + p->sas_ss_sp = p->sas_ss_size = 0; + + /* * Syscall tracing should be turned off in the child regardless * of CLONE_PTRACE. */ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/