From owner-svn-src-all@FreeBSD.ORG Wed Nov 26 14:09:05 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C3CF81A9; Wed, 26 Nov 2014 14:09:05 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B093FDA7; Wed, 26 Nov 2014 14:09:05 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sAQE95FL070877; Wed, 26 Nov 2014 14:09:05 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sAQE95jv070876; Wed, 26 Nov 2014 14:09:05 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201411261409.sAQE95jv070876@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Wed, 26 Nov 2014 14:09:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r275120 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Nov 2014 14:09:06 -0000 Author: kib Date: Wed Nov 26 14:09:04 2014 New Revision: 275120 URL: https://svnweb.freebsd.org/changeset/base/275120 Log: Fix SA_SIGINFO | SA_RESETHAND handling. The sysent' sv_sendsig() method needs pre-reset state of the ps_siginfo to correctly construct signal frame. Move sigdflt() call after the sv_sendsig() invocation in postsig(). Simultaneously extract common code from trapsignal() and postsig() into new helper postsig_done(). Submitted by: rea MFC after: 1 week Modified: head/sys/kern/kern_sig.c Modified: head/sys/kern/kern_sig.c ============================================================================== --- head/sys/kern/kern_sig.c Wed Nov 26 14:01:27 2014 (r275119) +++ head/sys/kern/kern_sig.c Wed Nov 26 14:09:04 2014 (r275120) @@ -1882,6 +1882,30 @@ pgsignal(struct pgrp *pgrp, int sig, int } } + +/* + * Recalculate the signal mask and reset the signal disposition after + * usermode frame for delivery is formed. Should be called after + * mach-specific routine, because sysent->sv_sendsig() needs correct + * ps_siginfo and signal mask. + */ +static void +postsig_done(int sig, struct thread *td, struct sigacts *ps) +{ + sigset_t mask; + + mtx_assert(&ps->ps_mtx, MA_OWNED); + td->td_ru.ru_nsignals++; + mask = ps->ps_catchmask[_SIG_IDX(sig)]; + if (!SIGISMEMBER(ps->ps_signodefer, sig)) + SIGADDSET(mask, sig); + kern_sigprocmask(td, SIG_BLOCK, &mask, NULL, + SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED); + if (SIGISMEMBER(ps->ps_sigreset, sig)) + sigdflt(ps, sig); +} + + /* * Send a signal caused by a trap to the current thread. If it will be * caught immediately, deliver it with correct code. Otherwise, post it @@ -1891,7 +1915,6 @@ void trapsignal(struct thread *td, ksiginfo_t *ksi) { struct sigacts *ps; - sigset_t mask; struct proc *p; int sig; int code; @@ -1906,7 +1929,6 @@ trapsignal(struct thread *td, ksiginfo_t mtx_lock(&ps->ps_mtx); if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(ps->ps_sigcatch, sig) && !SIGISMEMBER(td->td_sigmask, sig)) { - td->td_ru.ru_nsignals++; #ifdef KTRACE if (KTRPOINT(curthread, KTR_PSIG)) ktrpsig(sig, ps->ps_sigact[_SIG_IDX(sig)], @@ -1914,13 +1936,7 @@ trapsignal(struct thread *td, ksiginfo_t #endif (*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], ksi, &td->td_sigmask); - mask = ps->ps_catchmask[_SIG_IDX(sig)]; - if (!SIGISMEMBER(ps->ps_signodefer, sig)) - SIGADDSET(mask, sig); - kern_sigprocmask(td, SIG_BLOCK, &mask, NULL, - SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED); - if (SIGISMEMBER(ps->ps_sigreset, sig)) - sigdflt(ps, sig); + postsig_done(sig, td, ps); mtx_unlock(&ps->ps_mtx); } else { /* @@ -2802,7 +2818,7 @@ postsig(sig) struct sigacts *ps; sig_t action; ksiginfo_t ksi; - sigset_t returnmask, mask; + sigset_t returnmask; KASSERT(sig != 0, ("postsig")); @@ -2857,20 +2873,12 @@ postsig(sig) } else returnmask = td->td_sigmask; - mask = ps->ps_catchmask[_SIG_IDX(sig)]; - if (!SIGISMEMBER(ps->ps_signodefer, sig)) - SIGADDSET(mask, sig); - kern_sigprocmask(td, SIG_BLOCK, &mask, NULL, - SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED); - - if (SIGISMEMBER(ps->ps_sigreset, sig)) - sigdflt(ps, sig); - td->td_ru.ru_nsignals++; if (p->p_sig == sig) { p->p_code = 0; p->p_sig = 0; } (*p->p_sysent->sv_sendsig)(action, &ksi, &returnmask); + postsig_done(sig, td, ps); } return (1); }