From patchwork Mon Feb 12 12:42:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 128016 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3171296ljc; Mon, 12 Feb 2018 04:42:45 -0800 (PST) X-Google-Smtp-Source: AH8x224Hy7cDowr0GLLRkzEi5ldVOOuFeZ2pJ3Mc9IYpKsEl8BJVtS7l4HYVKcot9Ad0b0UHPF9j X-Received: by 10.99.189.82 with SMTP id d18mr9154908pgp.41.1518439364872; Mon, 12 Feb 2018 04:42:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518439364; cv=none; d=google.com; s=arc-20160816; b=EL7BAC6itrl7haLzIVIO8T+RAh3IEiifbkr7vZflSzaOeLsL0ent+rxAvwTOfKm3Pd kbooXUHji01W6rPWked4KKGAOPuwdCuBSPHqXkTmP7VCqRMvEn7xBT94aAxJ2pG4d2xD MN+XB8UV3gyhdS81Bogmyodm1PM1WjprlMyWuJvylgYNmanmvbUWfpjeo7SZsVEMBYFf aI4RlrBN/1ad7Dop3C6XceKX0x/Y47pJZH8rSmaS+Q4bvCt3DSNvnek12gK9+CoVS5Ua DINHeNXhyeQXVLS35/CuN+6xio8Ockv1VI4yu4ZeWoQ+MOnCatZb6EE8z3fx/nJORP9Z eLUg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:to:from:delivered-to:sender:list-help :list-post:list-archive:list-subscribe:list-unsubscribe:list-id :precedence:mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=HSBUXbnH2wAUl6k4OVzH0x6XePO2Mj54JpwbEjFrzxc=; b=sOIJ1uTvBy6uHeF5S4OGSdXotfssNwaIfz8K8HdKd+oxwJMS2SU0CbjvRBwM6PbOQb vx3yhdKRytw8pVVqQeXMbbxKXqMYgkDtt+H7IktWlWkMVMHEtSPud1HXG1F9kqpKXL19 fdgGLM6A2BN8nFOmNyiLqsNMO5ty2W1KiKBidGP/t3J0IewSLstOu/o4Gl8mqEfgXEfm +4d4T3LOwhUBxoGAErmoss+jnNV8Cy4WRVKuBy5UN4UU88PocMG6pl9yVI6Pc1oXBdtA AjXnP/fv2vLlK4Z0fjVeac+b25Z1LC345yiKFyM0nJUXKBSDRaX9gZTJdnJZqp0p8ZrO 3uvQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=gb+M2641; spf=pass (google.com: domain of libc-alpha-return-90257-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90257-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id g24si3371319pfd.140.2018.02.12.04.42.44 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Feb 2018 04:42:44 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-90257-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=gb+M2641; spf=pass (google.com: domain of libc-alpha-return-90257-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90257-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; q=dns; s= default; b=AWmMv/SJkKmw2P13b8SfJC3p2G9BhB4uv5ddWUykWi075Bb1QKjvs KbEJDApTvSJYRkIyR0lsbNEDQBHhx7clWBdt/qGWk/CUrP9Sq6o7B2WI209oYP/x bh8gpaTMBs15WlnkRHeYLozSXtvCO4TJAEY+hDvzm29iWnIbcxuy8Q= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; s=default; bh=mIKTUvqCrkrtl1CgK72zmF7nJHA=; b=gb+M2641AEu3yO7Xt+37uh07GRN2 47+aarQUpw1dfig8cveGN0LFelY/uLoeQKk2wHNCON7hC9zRXWX7uRBumaOOsOJ1 TxoGXo+XvdbA1teFIiY76L+J0xvVRFbAAbe2uRvo59TKjhx419ZlloAiePIjGa1V 2B/qf1YtkZgmVIY= Received: (qmail 51341 invoked by alias); 12 Feb 2018 12:42:35 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 51331 invoked by uid 89); 12 Feb 2018 12:42:34 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=sk:__inter X-HELO: mail-qt0-f194.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=HSBUXbnH2wAUl6k4OVzH0x6XePO2Mj54JpwbEjFrzxc=; b=Hp2gUvnYD/WplzsrfQMPELzteLSnpvJqZpfTBWh2ih1EWfQdMdGpN89pBe++KZ/rIY WnTK0Hbl9tC64Wz8YxtVH6atGx/KYiXKcG4vB7/x4pHWUWtKMMY+4nT6PClRhgviJw4e dA66g5k+K3eW76PxMmvNHj1vMZZHhW6f4oLy449lrOB/3VSlmC+GcnyEpuW3BvKi691d Xg+jg5kgRcWKh9MlS0x9Gu0bz1SUkbrz1YfM4QLwUclJ/yFzqCDpwa1l00Flw+Qp/nNZ 8/SIfrgoOBPddkk2MdS4nZaH8ZHZmDs2MxfxILIw42cVW/pokmfJaZ5rxQtpF/1N33ya mTSw== X-Gm-Message-State: APf1xPBSVP9vFDYjnncW11a9SjKTdnp5GSVXn475YMzKRFYJPkW47ktc HAuExgGc5aKwwDma/3Z/xg3D9Teu3fM= X-Received: by 10.200.54.151 with SMTP id a23mr9570371qtc.123.1518439350647; Mon, 12 Feb 2018 04:42:30 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v4 1/4] Rename nptl-signals.h to internal-signals.h Date: Mon, 12 Feb 2018 10:42:22 -0200 Message-Id: <1518439345-6013-1-git-send-email-adhemerval.zanella@linaro.org> Changes from previous version: - Fixed documentation issues pointed out by Rical Jasan. -- This patch renames the nptl-signals.h header to internal-signals.h. On Linux the definitions and functions are not only NPTL related, but used for other POSIX definitions as well (for instance SIGTIMER for posix times, SIGSETXID for id functions, and signal block/restore helpers) and since generic functions will be places and used in generic implementation it makes more sense to decouple it from NPTL. Checked on x86_64-linux-gnu. * sysdeps/nptl/nptl-signals.h: Move to ... * sysdeps/generic/internal-signals.h: ... here. Adjust internal comments. * sysdeps/unix/sysv/linux/internal-signals.h: Add include guards. (__nptl_is_internal_signal): Rename to __is_internal_signal. (__nptl_clear_internal_signals): Rename to __clear_internal_signals. * sysdeps/unix/sysv/linux/raise.c: Adjust nptl-signal.h to include-signals.h rename. * nptl/pthreadP.h: Likewise. * sysdeps/unix/sysv/linux/spawni.c (__spawni_child): Call __is_internal_signal instead of __nptl_is_internal_signal. Signed-off-by: Adhemerval Zanella --- ChangeLog | 14 ++++++++++++++ nptl/pthreadP.h | 2 +- .../{nptl/nptl-signals.h => generic/internal-signals.h} | 7 +------ .../sysv/linux/{nptl-signals.h => internal-signals.h} | 16 ++++++++++------ sysdeps/unix/sysv/linux/raise.c | 2 +- sysdeps/unix/sysv/linux/spawni.c | 2 +- 6 files changed, 28 insertions(+), 15 deletions(-) rename sysdeps/{nptl/nptl-signals.h => generic/internal-signals.h} (74%) rename sysdeps/unix/sysv/linux/{nptl-signals.h => internal-signals.h} (89%) -- 2.7.4 diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 583515f..075530c 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include /* Atomic operations on TLS memory. */ diff --git a/sysdeps/nptl/nptl-signals.h b/sysdeps/generic/internal-signals.h similarity index 74% rename from sysdeps/nptl/nptl-signals.h rename to sysdeps/generic/internal-signals.h index e1275c7..01e5b75 100644 --- a/sysdeps/nptl/nptl-signals.h +++ b/sysdeps/generic/internal-signals.h @@ -1,4 +1,4 @@ -/* Special use of signals in NPTL internals. Stub version. +/* Special use of signals internally. Stub version. Copyright (C) 2014-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -15,8 +15,3 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see . */ - -/* This file can define the macros SIGCANCEL, SIGTIMER, and SIGSETXID to - signal numbers reserved by libpthread for those internal purposes. - - Note that some code presumes SIGTIMER is the same as SIGCANCEL. */ diff --git a/sysdeps/unix/sysv/linux/nptl-signals.h b/sysdeps/unix/sysv/linux/internal-signals.h similarity index 89% rename from sysdeps/unix/sysv/linux/nptl-signals.h rename to sysdeps/unix/sysv/linux/internal-signals.h index e789198..e007372 100644 --- a/sysdeps/unix/sysv/linux/nptl-signals.h +++ b/sysdeps/unix/sysv/linux/internal-signals.h @@ -1,4 +1,4 @@ -/* Special use of signals in NPTL internals. Linux version. +/* Special use of signals internally. Linux version. Copyright (C) 2014-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -16,6 +16,9 @@ License along with the GNU C Library; if not, see . */ +#ifndef __INTERNAL_SIGNALS_H +# define __INTERNAL_SIGNALS_H + #include #include @@ -35,17 +38,16 @@ /* Return is sig is used internally. */ static inline int -__nptl_is_internal_signal (int sig) +__is_internal_signal (int sig) { - return (sig == SIGCANCEL) || (sig == SIGTIMER) || (sig == SIGSETXID); + return (sig == SIGCANCEL) || (sig == SIGSETXID); } /* Remove internal glibc signal from the mask. */ static inline void -__nptl_clear_internal_signals (sigset_t *set) +__clear_internal_signals (sigset_t *set) { __sigdelset (set, SIGCANCEL); - __sigdelset (set, SIGTIMER); __sigdelset (set, SIGSETXID); } @@ -66,7 +68,7 @@ static inline int __libc_signal_block_app (sigset_t *set) { sigset_t allset = SIGALL_SET; - __nptl_clear_internal_signals (&allset); + __clear_internal_signals (&allset); INTERNAL_SYSCALL_DECL (err); return INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_BLOCK, &allset, set, _NSIG / 8); @@ -83,3 +85,5 @@ __libc_signal_restore_set (const sigset_t *set) /* Used to communicate with signal handler. */ extern struct xid_command *__xidcmd attribute_hidden; + +#endif diff --git a/sysdeps/unix/sysv/linux/raise.c b/sysdeps/unix/sysv/linux/raise.c index cb98f90..b05eae2 100644 --- a/sysdeps/unix/sysv/linux/raise.c +++ b/sysdeps/unix/sysv/linux/raise.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include int raise (int sig) diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c index 6b699a4..0391b9b 100644 --- a/sysdeps/unix/sysv/linux/spawni.c +++ b/sysdeps/unix/sysv/linux/spawni.c @@ -144,7 +144,7 @@ __spawni_child (void *arguments) } else if (sigismember (&hset, sig)) { - if (__nptl_is_internal_signal (sig)) + if (__is_internal_signal (sig)) sa.sa_handler = SIG_IGN; else { From patchwork Mon Feb 12 12:42:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 128017 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3171424ljc; Mon, 12 Feb 2018 04:42:54 -0800 (PST) X-Google-Smtp-Source: AH8x2248SXDdAe+hnVlKGG67/FEJt7Y8KCB46UmOVVVDSj4ez1ev6YMbM2Js889vQzUHWMZhCiao X-Received: by 2002:a17:902:8ec4:: with SMTP id x4-v6mr10294684plo.271.1518439374863; Mon, 12 Feb 2018 04:42:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518439374; cv=none; d=google.com; s=arc-20160816; b=XNzUdMoaWhmnEX1LgEBJadELz+U9/skurhTkgteEGM4KBvZt6hK9yoQvPkhd3fCpSW 2kUEfLHFxTkaSQkqWPzHKPz6NPMj37ogqCVTwgnDmEcCllAKVJbE+2DPmCkk6y8E+/qn RuViBpg0yr34ycKTCzSFY5XScDSjv+b965XCclNKQpjSj4nyj4331DNid/bu55X0x1WG kzNjvVIWijArXrJkXXVtILa5g/8gHx7B4DGO3vZXTxN6dWGuRFmcH5rUfSrZ2hPH1uKO yzxsXUljxIGs0ZR7b+BA+uin0IdgpgW3GlXCB22jEHMxwiodADPIIqexyA1dILWaNOuB zuFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=E19VUyJfEkXLOWNtIkWH9c3D4sZBDS6RGh8OqJl9W2A=; b=EnZ+y80WowAugdr2vGHH7usTB7DRdYfDYmGGsz+V4D3OnMsyl384QzI1bQX6pPuQVH xmRhDgIusVaV3VvUrC91TcoPQov8OrlhfTDgJ+pGrP17bzBuH9pFbiS4aRykLnJIgyWx 2S5QKhcTvxF5s3tO5Rhdr6jo4ap4kV/ccjlgad+v3uYX3nBsQva5RBlnoW3TGV2esswQ +vJua+VJTE/dnPwki3rih8gyrp37K72XWDZessGtJaJupFqWdvqV6KawCyxMZLuHbQXY o+UK6+Omf1SV4IVSo+E6DMPTmM8E6I8+bfjt+GGFmw/gGRXiySG3gzXCbv0/oqY3B+WY RZUw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=WJT13Lzz; spf=pass (google.com: domain of libc-alpha-return-90258-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90258-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id c17-v6si1198190plo.118.2018.02.12.04.42.54 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Feb 2018 04:42:54 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-90258-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=WJT13Lzz; spf=pass (google.com: domain of libc-alpha-return-90258-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90258-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=fqrB90gO95g6rJLZlgMtDXM+RxOJvjX VSqwUZwf+4+eSbrRr3D7im2xn7d7UJ1qH7NHn7qhyorCJuDYUg153OnKOi3To9c6 dwR/s/5vkQa5ADN1JcYNsM3E8Qx+YQysWUWmpnnPvI6WLjcmM5Ug9O90HfKmvsBk Wi+9sSFQAb50= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=BrlCZDkers+J4R/iQN7OmVm1eH0=; b=WJT13 LzzmzPlLqPVpGmkesxJ6Y3YsgVfy5CG3jVu0AZp3drEtNkIwkIxfvloMOIStP34K Fv1IDbmyg/Kqjewt+CGBDeG7msqkV90RTa8ZdbXxXXkr5YecWxxjTgrgLBpBEDQs Nec2Do4DpJb5Zn3PBrumafQmwJoFV7vB66BEBk= Received: (qmail 51747 invoked by alias); 12 Feb 2018 12:42:38 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 51617 invoked by uid 89); 12 Feb 2018 12:42:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=2421, TRY X-HELO: mail-qt0-f178.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=E19VUyJfEkXLOWNtIkWH9c3D4sZBDS6RGh8OqJl9W2A=; b=ARTMMkboPx7KhYF5fJ5GM5zV+5Pnfe5gLXjFvFt8SDQiebe/ggzBOiNX6/KxyCxczX SZCrONlCfF3XbAF2ITZAWiZJWtFoKYBAwIqTTpTE9k9Lzy3QiU79eJJAYCtzddpCPo5H nIZjVX5DRdt1uSACWpsgekwDrDZU8dp3UpkXEMIzvZ1kFXk2T4b968Sgkx7qkpsWiYVQ tswiskrX8xkcZskTLIz9dy+A0PFSU6EaH61h/dEekCa2mbuabxrb5YIBTiZjNl87sd20 oN5XqdY23DRH2VA6nvb/zA7d4/QvgwtTf9YraPrw2QWR+emSsjEiXCNW1J7d3tB3x1IE Cl8A== X-Gm-Message-State: APf1xPBnc6KkyGg2okaT4LZ0IWLL/7YwmXLkmLpaczBjr33pY+L4dgen tqsir5yHYS8w5/GCrj17cCTTwYZ3Yi0= X-Received: by 10.200.57.97 with SMTP id t30mr15020601qtb.22.1518439352375; Mon, 12 Feb 2018 04:42:32 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v4 2/4] Filter out NPTL internal signals (BZ #22391) Date: Mon, 12 Feb 2018 10:42:23 -0200 Message-Id: <1518439345-6013-2-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1518439345-6013-1-git-send-email-adhemerval.zanella@linaro.org> References: <1518439345-6013-1-git-send-email-adhemerval.zanella@linaro.org> This patch filters out the internal NPTL signals (SIGCANCEL/SIGTIMER and SIGSETXID) from signal functions. GLIBC on Linux requires both signals to proper implement pthread cancellation, posix timers, and set*id posix thread synchronization. And not filtering out the internal signal is troublesome: - A conformant program on a architecture that does not filter out the signals might inadvertently disable pthread asynchronous cancellation, set*id synchronization or posix timers. - It might also to security issues if SIGSETXID is masked and set*id functions are called (some threads might have effective user or group id different from the rest). The changes are basically: - Change __is_internal_signal to bool and used on all signal function that has a signal number as input. Also for signal function which accepts signals sets (sigset_t) it assumes that canonical function were used to add/remove signals which lead to some input simplification. - Fix tst-sigset.c to avoid check for SIGCANCEL/SIGTIMER and SIGSETXID. It is rewritten to check each signal indidually and to check realtime signals using canonical macros. - Add generic __clear_internal_signals and __is_internal_signal version since both symbols are used on generic implementations. - Remove superflous sysdeps/nptl/sigfillset.c. - Remove superflous SIGTIMER handling on Linux __is_internal_signal since it is the same of SIGCANCEL. - Remove dangling define and obvious comment on nptl/sigaction.c. Checked on x86_64-linux-gnu. [BZ #22391] * nptl/sigaction.c (__sigaction): Use __is_internal_signal to check for internal nptl signals. * signal/sigaddset.c (sigaddset): Likewise. * signal/sigdelset.c (sigdelset): Likewise. * sysdeps/posix/signal.c (__bsd_signal): Likewise. * sysdeps/posix/sigset.c (sigset): Call and check sigaddset return value. * signal/sigfillset.c (sigfillset): User __clear_internal_signals to filter out internal nptl signals. * signal/tst-sigset.c (do_test): Check ech signal indidually and also check realtime signals using standard macros. * sysdeps/nptl/nptl-signals.h (__clear_internal_signals, __is_internal_signal): New functions. * sysdeps/nptl/sigfillset.c: Remove file. * sysdeps/unix/sysv/linux/nptl-signals.h (__is_internal_signal): Change return to bool. (__clear_internal_signals): Remove SIGTIMER clean since it is equal to SIGCANEL on Linux. * sysdeps/unix/sysv/linux/sigtimedwait.c (__sigtimedwait): Assume signal set was constructed using standard functions. * sysdeps/unix/sysv/linux/sigwait.c (do_sigtwait): Likewise. Signed-off-by: Adhemerval Zanella Reported-by: Yury Norov --- ChangeLog | 23 ++++++++ nptl/sigaction.c | 14 +---- signal/sigaction.c | 2 +- signal/sigaddset.c | 5 +- signal/sigdelset.c | 5 +- signal/sigfillset.c | 10 +--- signal/tst-sigset.c | 92 ++++++++++++++++++++++-------- sysdeps/generic/internal-signals.h | 11 ++++ sysdeps/nptl/sigfillset.c | 20 ------- sysdeps/posix/signal.c | 5 +- sysdeps/posix/sigset.c | 10 +--- sysdeps/unix/sysv/linux/internal-signals.h | 4 +- sysdeps/unix/sysv/linux/sigtimedwait.c | 17 +----- 13 files changed, 122 insertions(+), 96 deletions(-) delete mode 100644 sysdeps/nptl/sigfillset.c -- 2.7.4 diff --git a/nptl/sigaction.c b/nptl/sigaction.c index ddf6f5e..79b6fdc 100644 --- a/nptl/sigaction.c +++ b/nptl/sigaction.c @@ -16,22 +16,12 @@ License along with the GNU C Library; if not, see . */ - -/* This is no complete implementation. The file is meant to be - included in the real implementation to provide the wrapper around - __libc_sigaction. */ - -#include - -/* We use the libc implementation but we tell it to not allow - SIGCANCEL or SIGTIMER to be handled. */ -#define LIBC_SIGACTION 1 - +#include int __sigaction (int sig, const struct sigaction *act, struct sigaction *oact) { - if (__glibc_unlikely (sig == SIGCANCEL || sig == SIGSETXID)) + if (sig <= 0 || sig >= NSIG || __is_internal_signal (sig)) { __set_errno (EINVAL); return -1; diff --git a/signal/sigaction.c b/signal/sigaction.c index f761ca2..c99001a 100644 --- a/signal/sigaction.c +++ b/signal/sigaction.c @@ -24,7 +24,7 @@ int __sigaction (int sig, const struct sigaction *act, struct sigaction *oact) { - if (sig <= 0 || sig >= NSIG) + if (sig <= 0 || sig >= NSIG || __is_internal_signal (sig)) { __set_errno (EINVAL); return -1; diff --git a/signal/sigaddset.c b/signal/sigaddset.c index d310890..7238df4 100644 --- a/signal/sigaddset.c +++ b/signal/sigaddset.c @@ -17,13 +17,14 @@ #include #include -#include +#include /* Add SIGNO to SET. */ int sigaddset (sigset_t *set, int signo) { - if (set == NULL || signo <= 0 || signo >= NSIG) + if (set == NULL || signo <= 0 || signo >= NSIG + || __is_internal_signal (signo)) { __set_errno (EINVAL); return -1; diff --git a/signal/sigdelset.c b/signal/sigdelset.c index cd83dda..011978c 100644 --- a/signal/sigdelset.c +++ b/signal/sigdelset.c @@ -17,13 +17,14 @@ #include #include -#include +#include /* Add SIGNO to SET. */ int sigdelset (sigset_t *set, int signo) { - if (set == NULL || signo <= 0 || signo >= NSIG) + if (set == NULL || signo <= 0 || signo >= NSIG + || __is_internal_signal (signo)) { __set_errno (EINVAL); return -1; diff --git a/signal/sigfillset.c b/signal/sigfillset.c index e586fd9..83dd583 100644 --- a/signal/sigfillset.c +++ b/signal/sigfillset.c @@ -18,6 +18,7 @@ #include #include #include +#include /* Set all signals in SET. */ int @@ -31,14 +32,7 @@ sigfillset (sigset_t *set) memset (set, 0xff, sizeof (sigset_t)); - /* If the implementation uses a cancellation signal don't set the bit. */ -#ifdef SIGCANCEL - __sigdelset (set, SIGCANCEL); -#endif - /* Likewise for the signal to implement setxid. */ -#ifdef SIGSETXID - __sigdelset (set, SIGSETXID); -#endif + __clear_internal_signals (set); return 0; } diff --git a/signal/tst-sigset.c b/signal/tst-sigset.c index d47adcc..a2b764d 100644 --- a/signal/tst-sigset.c +++ b/signal/tst-sigset.c @@ -1,43 +1,85 @@ /* Test sig*set functions. */ #include -#include -#define TEST_FUNCTION do_test () +#include + static int do_test (void) { - int result = 0; - int sig = -1; + sigset_t set; + TEST_VERIFY (sigemptyset (&set) == 0); -#define TRY(call) \ - if (call) \ - { \ - printf ("%s (sig = %d): %m\n", #call, sig); \ - result = 1; \ - } \ - else +#define VERIFY(set, sig) \ + TEST_VERIFY (sigismember (&set, sig) == 0); \ + TEST_VERIFY (sigaddset (&set, sig) == 0); \ + TEST_VERIFY (sigismember (&set, sig) != 0); \ + TEST_VERIFY (sigdelset (&set, sig) == 0); \ + TEST_VERIFY (sigismember (&set, sig) == 0) + /* ISO C99 signals. */ + VERIFY (set, SIGINT); + VERIFY (set, SIGILL); + VERIFY (set, SIGABRT); + VERIFY (set, SIGFPE); + VERIFY (set, SIGSEGV); + VERIFY (set, SIGTERM); - sigset_t set; - TRY (sigemptyset (&set) != 0); + /* Historical signals specified by POSIX. */ + VERIFY (set, SIGHUP); + VERIFY (set, SIGQUIT); + VERIFY (set, SIGTRAP); + VERIFY (set, SIGKILL); + VERIFY (set, SIGBUS); + VERIFY (set, SIGSYS); + VERIFY (set, SIGPIPE); + VERIFY (set, SIGALRM); + + /* New(er) POSIX signals (1003.1-2008, 1003.1-2013). */ + VERIFY (set, SIGURG); + VERIFY (set, SIGSTOP); + VERIFY (set, SIGTSTP); + VERIFY (set, SIGCONT); + VERIFY (set, SIGCHLD); + VERIFY (set, SIGTTIN); + VERIFY (set, SIGTTOU); + VERIFY (set, SIGPOLL); + VERIFY (set, SIGXCPU); + VERIFY (set, SIGXFSZ); + VERIFY (set, SIGVTALRM); + VERIFY (set, SIGPROF); + VERIFY (set, SIGUSR1); + VERIFY (set, SIGUSR2); + + /* Nonstandard signals found in all modern POSIX systems + (including both BSD and Linux). */ + VERIFY (set, SIGWINCH); -#ifdef SIGRTMAX - int max_sig = SIGRTMAX; -#else - int max_sig = NSIG - 1; + /* Arch-specific signals. */ +#ifdef SIGEMT + VERIFY (set, SIGEMT); +#endif +#ifdef SIGLOST + VERIFY (set, SIGLOST); +#endif +#ifdef SIGINFO + VERIFY (set, SIGINFO); +#endif +#ifdef SIGSTKFLT + VERIFY (set, SIGSTKFLT); +#endif +#ifdef SIGPWR + VERIFY (set, SIGPWR); #endif - for (sig = 1; sig <= max_sig; ++sig) + /* Read-time signals (POSIX.1b real-time extensions). If they are + supported SIGRTMAX value is greater than SIGRTMIN. */ + for (int rtsig = SIGRTMIN; rtsig <= SIGRTMAX; rtsig++) { - TRY (sigismember (&set, sig) != 0); - TRY (sigaddset (&set, sig) != 0); - TRY (sigismember (&set, sig) == 0); - TRY (sigdelset (&set, sig) != 0); - TRY (sigismember (&set, sig) != 0); + VERIFY (set, rtsig); } - return result; + return 0; } -#include "../test-skeleton.c" +#include diff --git a/sysdeps/generic/internal-signals.h b/sysdeps/generic/internal-signals.h index 01e5b75..ab0b22e 100644 --- a/sysdeps/generic/internal-signals.h +++ b/sysdeps/generic/internal-signals.h @@ -15,3 +15,14 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see . */ + +static inline void +__clear_internal_signals (sigset_t *set) +{ +} + +static inline bool +__is_internal_signal (int sig) +{ + return false; +} diff --git a/sysdeps/nptl/sigfillset.c b/sysdeps/nptl/sigfillset.c deleted file mode 100644 index 94a7680..0000000 --- a/sysdeps/nptl/sigfillset.c +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (C) 2003-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include - -#include diff --git a/sysdeps/posix/signal.c b/sysdeps/posix/signal.c index a4a0875..8a135c7 100644 --- a/sysdeps/posix/signal.c +++ b/sysdeps/posix/signal.c @@ -18,8 +18,8 @@ #include #include -#include /* For the real memset prototype. */ #include +#include sigset_t _sigintr attribute_hidden; /* Set by siginterrupt. */ @@ -31,7 +31,8 @@ __bsd_signal (int sig, __sighandler_t handler) struct sigaction act, oact; /* Check signal extents to protect __sigismember. */ - if (handler == SIG_ERR || sig < 1 || sig >= NSIG) + if (handler == SIG_ERR || sig < 1 || sig >= NSIG + || __is_internal_signal (sig)) { __set_errno (EINVAL); return SIG_ERR; diff --git a/sysdeps/posix/sigset.c b/sysdeps/posix/sigset.c index b62aa3c..6ab4a48 100644 --- a/sysdeps/posix/sigset.c +++ b/sysdeps/posix/sigset.c @@ -31,15 +31,9 @@ sigset (int sig, __sighandler_t disp) sigset_t set; sigset_t oset; - /* Check signal extents to protect __sigismember. */ - if (disp == SIG_ERR || sig < 1 || sig >= NSIG) - { - __set_errno (EINVAL); - return SIG_ERR; - } - __sigemptyset (&set); - __sigaddset (&set, sig); + if (sigaddset (&set, sig) < 0) + return SIG_ERR; if (disp == SIG_HOLD) { diff --git a/sysdeps/unix/sysv/linux/internal-signals.h b/sysdeps/unix/sysv/linux/internal-signals.h index e007372..5ff4cf8 100644 --- a/sysdeps/unix/sysv/linux/internal-signals.h +++ b/sysdeps/unix/sysv/linux/internal-signals.h @@ -21,6 +21,8 @@ #include #include +#include +#include /* The signal used for asynchronous cancelation. */ #define SIGCANCEL __SIGRTMIN @@ -37,7 +39,7 @@ /* Return is sig is used internally. */ -static inline int +static inline bool __is_internal_signal (int sig) { return (sig == SIGCANCEL) || (sig == SIGSETXID); diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c index 051a285..b4de885 100644 --- a/sysdeps/unix/sysv/linux/sigtimedwait.c +++ b/sysdeps/unix/sysv/linux/sigtimedwait.c @@ -24,21 +24,8 @@ int __sigtimedwait (const sigset_t *set, siginfo_t *info, const struct timespec *timeout) { - sigset_t tmpset; - if (set != NULL - && (__builtin_expect (__sigismember (set, SIGCANCEL), 0) - || __builtin_expect (__sigismember (set, SIGSETXID), 0))) - { - /* Create a temporary mask without the bit for SIGCANCEL set. */ - // We are not copying more than we have to. - memcpy (&tmpset, set, _NSIG / 8); - __sigdelset (&tmpset, SIGCANCEL); - __sigdelset (&tmpset, SIGSETXID); - set = &tmpset; - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ + /* XXX The size argument hopefully will have to be changed to the + real size of the user-level sigset_t. */ int result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, timeout, _NSIG / 8); /* The kernel generates a SI_TKILL code in si_code in case tkill is From patchwork Mon Feb 12 12:42:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 128018 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3171629ljc; Mon, 12 Feb 2018 04:43:09 -0800 (PST) X-Google-Smtp-Source: AH8x225WhAtsAb8/6T6vQwvsOTFs5YTluTWRsUNoU6ORsftNc0+B+cB5GP5JRpXOT3lg+MZ5kOlI X-Received: by 10.101.101.143 with SMTP id u15mr9112715pgv.265.1518439389427; Mon, 12 Feb 2018 04:43:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518439389; cv=none; d=google.com; s=arc-20160816; b=qOHfcBLmqqPwQJe3B3e4H7/4pVgzijjpmDEHgwzM3U/dS6w9KMeN8nD36b46VdYz1m OVtwmCHNzKcn6ezQEjDCfy5T7GKN+5QwSAVODLT0PvLyR1eVYCJGzuiKWGKFJ8A5d0P0 vx1wSdMXg5Gj+fG7KHFftda432v4iA+9aKlI5RmvDyWqcD9pJulLRFTyEnKE5NX7CwK1 bt5Pe60ytmwo/kZ0MVpyd0P3vv/RuPM0ZGT7d/LiVHBxWqZrsuhCaF27H2vAmHvu6/e6 rxP7d9vjfqyh8auQ3h3BFNGfl8JAJl1L9ybO2jjaeIkiFPI/+oJQFH+Lh0gBrtsMBjgH TIUw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=Td9Zjjw+vhhxXAywl8CLnAhEMrG7E2g+Kj7lgXwc8Ug=; b=DBkIf3YIL/11bGvRtSPFSUHsC3zJ6xp6FvpOrygV0Tb0Mj51oHdByZ5Ye1564UIh5E shoHAwmV9AoHEJ6owxQEtSLIO5gXo7dwXrPkIPX8EgLRe+z+MTA7AYSX6vIOWxgebErF kg+Ib+5F3murXYZ5ar6ULngt7ZfsUMQUbPTiEtNMDF7JO9IbkEeTQk4pdDSNZgyAFa6O AR1GMBwiqmsUtiG8J9SW2sI73AseJ946usbhzNB7zoouFQLQ0FzhCO6hOLJIWRR7Ybht 4eB0YCssTMZq/J1FsKa3dnDbVoVxxuSHRHEZW6nDJQUpqDoGz0W9Q0Nop0VvJ6OqX+bX y7XA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=qXaaUudo; spf=pass (google.com: domain of libc-alpha-return-90259-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90259-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id a13si5093145pgu.178.2018.02.12.04.43.09 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Feb 2018 04:43:09 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-90259-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=qXaaUudo; spf=pass (google.com: domain of libc-alpha-return-90259-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90259-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=WLsBH2o0jQ69JmoJau1JJwh0KQnzJeR EnZZ3VdtPxSZiKX/rTp24/AAU7VyYuS5t8xRrY1MT8AkpHdn/No+UY3W16nmyHbC xPJ3PXklYspLOwUWhLY1oLNPq3ngv9veBrjT859qI+VzaMZI3L7q5CF6FkI4dFTg GZkU5/FU/K8k= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=ygWmZLF9h3xA75hnoSKQgExKfnc=; b=qXaaU udoZMVfmVRklCOOLZLRilwDtUMcD+SZRtqH9aQMNpzsX9Glc1/2wgE6djybsRYTj VWntskurVt49PMPnjioq1I8twThlwneSNVnbRJOsg+nbBlp5XMw32OvTe0fKTJjN oehjikVLMX0YCrRQQaL8yjozOS75pRZtFiz78U= Received: (qmail 52552 invoked by alias); 12 Feb 2018 12:42:45 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 52445 invoked by uid 89); 12 Feb 2018 12:42:44 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-qt0-f178.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=Td9Zjjw+vhhxXAywl8CLnAhEMrG7E2g+Kj7lgXwc8Ug=; b=iR7ayivKipsYdaZM+8K2mvIo5CWJ9TnGlmh3PXrxiG534rEUFwGw4GRQtuM+zpC63/ fY58+Kxy6kzASWLi0ijyGTw17IyhkcjUq7WIePs8EnrxOW455QwNcuKSMURGpsAf0Ajh 7thF5Pz9lKj8Dj4B+6+WfG4oh8GxVfReL3wNgF9d84jAvBnoaRDHy0B4m+H2YCOq1rYT 2kMhzdkX/Rr9y76JbebUf7cRahMk0UQcqCOfpSQXXPdi69Fl9WYoNUQGZADRBIoJYzEb IW4qVUFGP0bPtVvzkngKhv6NiWx0MK2U96Ndv1Zy3XcukLBpglaY41cv01MPup0fY/3l adiA== X-Gm-Message-State: APf1xPCQOupzd1idJ5YSd/g1GTALMaVGwkiAiWEDaQB5VIn4wPWqPv7v 928G7WD/GdBpseOFWVjhaX2BveriJts= X-Received: by 10.200.17.1 with SMTP id c1mr19277812qtj.150.1518439354199; Mon, 12 Feb 2018 04:42:34 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v4 3/4] linux: Consolidate sigaction implementation Date: Mon, 12 Feb 2018 10:42:24 -0200 Message-Id: <1518439345-6013-3-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1518439345-6013-1-git-send-email-adhemerval.zanella@linaro.org> References: <1518439345-6013-1-git-send-email-adhemerval.zanella@linaro.org> This patch consolidates all Linux sigaction implementation on a default one at sysdeps/unix/sysv/linux/sigaction.c. The idea is remove redundant code and simplify new ports addition by following the current generic Linux User API (UAPI). The UAPI for new ports defines a generic extensible sigaction struct as: struct sigaction { __sighandler_t sa_handler; unsigned long sa_flags; #ifdef SA_RESTORER void (*sa_restorer) (void); #endif sigset_t sa_mask; }; Where SA_RESTORER is just placed to compatibility reasons, news ports should not add it. A similar definition is used on generic kernel_sigaction.h. The user exported sigaction definition is not changed, so for most architectures it requires an adjustment to kernel expected one for the syscall. The main changes are: - All architectures now define and use a kernel_sigaction struct meant for the syscall, even for the architectures where the user sigaction has the same layout of the kernel expected one (s390-64 and ia64). Although it requires more work for these architectures, it simplifies the generic implementation. Also, sigaction is hardly a hotspot where micro optimization would play an important role. - The generic kernel_sigaction definition is now aligned with expected UAPI one for newer ports, where SA_RESTORER and sa_restorer is not expected to be defined. This means adding kernel_sigaction for current architectures that does define it (m68k, nios2, powerpc, s390, sh, sparc, and tile) and which rely on previous generic definition. - Remove old MIPS usage of sa_restorer. This was removed since 2.6.27 (2957c9e61ee9c - "[MIPS] IRIX: Goodbye and thanks for all the fish"). So for new ports the generic implementation should work if its uses Linux UAPI. If SA_RESTORER is still required (due some architecture limitation), it should define its own kernel_sigaction.h, define it and include generic header (assuming it still uses the default generic kernel layout). Checked on x86_64-linux-gnu, i686-linux-gnu, arm-linux-gnueabihf, aarch64-linux-gnu, sparc64-linux-gnu, sparcv9-linux-gnu, powerpc-linux-gnu, and powerpc64-linux-gnu. I also check the build on all remaining affected ABIs. * sysdeps/unix/sysv/linux/aarch64/sigaction.c: Use default Linux version as base implementation. * sysdeps/unix/sysv/linux/arm/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/i386/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/x86_64/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h: Add include guards, remove unrequired definitions and update comments. * sysdeps/unix/sysv/linux/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/mips/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h: New file. * sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/kernel_sigaction: Likewise. * sysdeps/unix/sysv/linux/s390/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/sh/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/tile/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/ia64/sigaction.c: Remove file. * sysdeps/unix/sysv/linux/mips/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/sigaction.c: Add STUB, SET_SA_RESTORER, and RESET_SA_RESTORER hooks. Signed-off-by: Adhemerval Zanella --- ChangeLog | 25 +++++ sysdeps/unix/sysv/linux/aarch64/sigaction.c | 58 ++--------- sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h | 21 ++-- sysdeps/unix/sysv/linux/arm/sigaction.c | 79 +++----------- sysdeps/unix/sysv/linux/i386/sigaction.c | 76 +++----------- sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h | 6 ++ sysdeps/unix/sysv/linux/ia64/sigaction.c | 45 -------- sysdeps/unix/sysv/linux/kernel_sigaction.h | 31 +++--- sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h | 22 ++++ sysdeps/unix/sysv/linux/mips/kernel_sigaction.h | 48 ++------- sysdeps/unix/sysv/linux/mips/sigaction.c | 116 --------------------- sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h | 8 ++ sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h | 8 ++ sysdeps/unix/sysv/linux/s390/kernel_sigaction.h | 28 +++++ sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c | 43 -------- sysdeps/unix/sysv/linux/sh/kernel_sigaction.h | 8 ++ sysdeps/unix/sysv/linux/sigaction.c | 28 ++--- sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h | 10 ++ sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c | 41 +------- sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c | 43 +------- sysdeps/unix/sysv/linux/tile/kernel_sigaction.h | 9 ++ sysdeps/unix/sysv/linux/x86_64/sigaction.c | 61 ++--------- 22 files changed, 230 insertions(+), 584 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h delete mode 100644 sysdeps/unix/sysv/linux/ia64/sigaction.c create mode 100644 sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h delete mode 100644 sysdeps/unix/sysv/linux/mips/sigaction.c create mode 100644 sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/s390/kernel_sigaction.h delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c create mode 100644 sysdeps/unix/sysv/linux/sh/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/tile/kernel_sigaction.h -- 2.7.4 diff --git a/sysdeps/unix/sysv/linux/aarch64/sigaction.c b/sysdeps/unix/sysv/linux/aarch64/sigaction.c index 73f4eb7..83d5b4f 100644 --- a/sysdeps/unix/sysv/linux/aarch64/sigaction.c +++ b/sysdeps/unix/sysv/linux/aarch64/sigaction.c @@ -1,5 +1,4 @@ /* Copyright (C) 1997-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,55 +15,16 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include - -#include -#include - +/* Required for AArch32 compatibility. */ #define SA_RESTORER 0x04000000 -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include - -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - struct kernel_sigaction kact; - struct kernel_sigaction koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER - if (kact.sa_flags & SA_RESTORER) - kact.sa_restorer = act->sa_restorer; -#endif - } +#define SET_SA_RESTORER(kact, act) \ + ({ \ + if ((kact)->sa_flags & SA_RESTORER) \ + (kact)->sa_restorer = (act)->sa_restorer; \ + }) - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - if (result >= 0 || errno != ENOSYS) - { - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif - } - } - return result; -} -libc_hidden_def (__libc_sigaction) +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer; -#include +#include diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h index 4c35d96..25180ff 100644 --- a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h +++ b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h @@ -1,15 +1,12 @@ -/* This is the sigaction struction from the Linux 2.1.20 kernel. */ +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H -struct old_kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_mask; - unsigned int sa_flags; +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + __sighandler_t k_sa_handler; + unsigned int sa_flags; + sigset_t sa_mask; }; -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ - -struct kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned int sa_flags; - sigset_t sa_mask; -}; +#endif diff --git a/sysdeps/unix/sysv/linux/arm/sigaction.c b/sysdeps/unix/sysv/linux/arm/sigaction.c index e4d80de..c828250 100644 --- a/sysdeps/unix/sysv/linux/arm/sigaction.c +++ b/sysdeps/unix/sysv/linux/arm/sigaction.c @@ -15,70 +15,25 @@ License along with the GNU C Library. If not, see . */ -#include -#include -#include - -#include -#include - -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include - #define SA_RESTORER 0x04000000 extern void __default_sa_restorer (void); extern void __default_rt_sa_restorer (void); -/* When RT signals are in use we need to use a different return stub. */ -#define choose_restorer(flags) \ - (flags & SA_SIGINFO) ? __default_rt_sa_restorer \ - : __default_sa_restorer - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER - if (kact.sa_flags & SA_RESTORER) - kact.sa_restorer = act->sa_restorer; - else - { - kact.sa_restorer = choose_restorer (kact.sa_flags); - kact.sa_flags |= SA_RESTORER; - } -#endif - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif - } - return result; -} -libc_hidden_def (__libc_sigaction) - -#include +#define SET_SA_RESTORER(kact, act) \ + ({ \ + if ((kact)->sa_flags & SA_RESTORER) \ + (kact)->sa_restorer = (act)->sa_restorer; \ + else \ + { \ + (kact)->sa_restorer = ((kact)->sa_flags & SA_SIGINFO) \ + ? __default_rt_sa_restorer \ + : __default_sa_restorer; \ + (kact)->sa_flags |= SA_RESTORER; \ + } \ + }) + +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer; + +#include diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c index a5eb9e0..137c73b 100644 --- a/sysdeps/unix/sysv/linux/i386/sigaction.c +++ b/sysdeps/unix/sysv/linux/i386/sigaction.c @@ -16,78 +16,28 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include #include -#include - -#include -#include #include -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include - -/* We do not globally define the SA_RESTORER flag so do it here. */ #define SA_RESTORER 0x04000000 - -/* Using the hidden attribute here does not change the code but it - helps to avoid warnings. */ -#ifdef __NR_rt_sigaction extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; -#endif extern void restore (void) asm ("__restore") attribute_hidden; +#define SET_SA_RESTORER(kact, act) \ + ({ \ + if (GLRO(dl_sysinfo_dso) == NULL) \ + { \ + (kact)->sa_flags |= SA_RESTORER; \ + (kact)->sa_restorer = (((act)->sa_flags & SA_SIGINFO) \ + ? &restore_rt : &restore); \ + } \ + }) -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - kact.sa_flags = act->sa_flags; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - - if (GLRO(dl_sysinfo_dso) == NULL) - { - kact.sa_flags |= SA_RESTORER; - - kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) - ? &restore_rt : &restore); - } - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - INTERNAL_SYSCALL_DECL (err); - result = INTERNAL_SYSCALL (rt_sigaction, err, 4, - sig, act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) - return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (result, - err)); - else if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - return result; -} -libc_hidden_def (__libc_sigaction) +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer -#include +#include /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to @@ -108,10 +58,8 @@ asm \ " int $0x80" \ ); -#ifdef __NR_rt_sigaction /* The return code for realtime-signals. */ RESTORE (restore_rt, __NR_rt_sigreturn) -#endif /* For the boring old signals. */ #undef RESTORE2 diff --git a/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h b/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h new file mode 100644 index 0000000..05813db --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h @@ -0,0 +1,6 @@ +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction { + __sighandler_t k_sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; /* mask last for extensibility */ +}; diff --git a/sysdeps/unix/sysv/linux/ia64/sigaction.c b/sysdeps/unix/sysv/linux/ia64/sigaction.c deleted file mode 100644 index e7fb8cd..0000000 --- a/sysdeps/unix/sysv/linux/ia64/sigaction.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 1997-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Linux/IA64 specific sigaction - Written by Jes Sorensen, , April 1999. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -/* Linux/ia64 only has rt signals, thus we do not even want to try falling - back to the old style signals as the default Linux handler does. */ - -#include -#include -#include - -#include -#include - -/* The variable is shared between all wrappers around signal handling - functions which have RT equivalents. This is the definition. */ - - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - return INLINE_SYSCALL (rt_sigaction, 4, sig, act, oact, _NSIG / 8); -} -libc_hidden_def (__libc_sigaction) - -#include diff --git a/sysdeps/unix/sysv/linux/kernel_sigaction.h b/sysdeps/unix/sysv/linux/kernel_sigaction.h index d005cbc..2dbec08 100644 --- a/sysdeps/unix/sysv/linux/kernel_sigaction.h +++ b/sysdeps/unix/sysv/linux/kernel_sigaction.h @@ -1,19 +1,20 @@ -/* This is the sigaction structure from the Linux 2.1.20 kernel. */ +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H -#define HAVE_SA_RESTORER - -struct old_kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_mask; - unsigned long sa_flags; - void (*sa_restorer) (void); +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + __sighandler_t k_sa_handler; + unsigned long sa_flags; +#ifdef SA_RESTORER + void (*sa_restorer) (void); +#endif + sigset_t sa_mask; }; -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ +#ifndef SA_RESTORER +# define SET_SA_RESTORER(kact, act) +# define RESET_SA_RESTORER(act, kact) +#endif -struct kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_flags; - void (*sa_restorer) (void); - sigset_t sa_mask; -}; +#endif diff --git a/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h new file mode 100644 index 0000000..54972fe --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h @@ -0,0 +1,22 @@ +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H + +#include + +#define SA_RESTORER 0x04000000 + +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + __sighandler_t k_sa_handler; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer) (void); +}; + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer + +#endif diff --git a/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h b/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h index b6f52cc..beef976 100644 --- a/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h +++ b/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h @@ -1,40 +1,12 @@ -/* This is the sigaction structure from the Linux 2.1.24 kernel. */ - -#include - -#define HAVE_SA_RESTORER - -struct old_kernel_sigaction { - unsigned int sa_flags; - __sighandler_t k_sa_handler; - unsigned long sa_mask; - unsigned int __pad0[3]; /* reserved, keep size constant */ - - /* Abi says here follows reserved int[2] */ - void (*sa_restorer)(void); -#if (_MIPS_SZPTR < 64) - /* - * For 32 bit code we have to pad struct sigaction to get - * constant size for the ABI - */ - int pad1[1]; /* reserved */ -#endif +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H + +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + unsigned int sa_flags; + __sighandler_t k_sa_handler; + sigset_t sa_mask; }; - -#define _KERNEL_NSIG 128 -#define _KERNEL_NSIG_BPW _MIPS_SZLONG -#define _KERNEL_NSIG_WORDS (_KERNEL_NSIG / _KERNEL_NSIG_BPW) - -typedef struct { - unsigned long sig[_KERNEL_NSIG_WORDS]; -} kernel_sigset_t; - -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ -struct kernel_sigaction { - unsigned int sa_flags; - __sighandler_t k_sa_handler; - kernel_sigset_t sa_mask; - void (*sa_restorer)(void); - int s_resv[1]; /* reserved */ -}; +#endif diff --git a/sysdeps/unix/sysv/linux/mips/sigaction.c b/sysdeps/unix/sysv/linux/mips/sigaction.c deleted file mode 100644 index 008b688..0000000 --- a/sysdeps/unix/sysv/linux/mips/sigaction.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (C) 1997-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library. If not, see - . */ - -#include -#include -#include -#include - -#include -#include - -#include - -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include - -#if _MIPS_SIM != _ABIO32 - -# ifdef __NR_rt_sigreturn -static void restore_rt (void) asm ("__restore_rt"); -# endif -# ifdef __NR_sigreturn -static void restore (void) asm ("__restore"); -# endif -#endif - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kernel_sigset_t)); - kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER -# if _MIPS_SIM == _ABIO32 - kact.sa_restorer = act->sa_restorer; -# else - kact.sa_restorer = &restore_rt; -# endif -#endif - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, - sizeof (kernel_sigset_t)); - - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, - sizeof (kernel_sigset_t)); - oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif - } - return result; -} -libc_hidden_def (__libc_sigaction) - -#include - - -/* NOTE: Please think twice before making any changes to the bits of - code below. GDB needs some intimate knowledge about it to - recognize them as signal trampolines, and make backtraces through - signal handlers work right. Important are both the names - (__restore_rt) and the exact instruction sequence. - If you ever feel the need to make any changes, please notify the - appropriate GDB maintainer. */ - -#define RESTORE(name, syscall) RESTORE2 (name, syscall) -#define RESTORE2(name, syscall) \ -asm \ - ( \ - ".align 4\n" \ - "__" #name ":\n" \ - " li $2, " #syscall "\n" \ - " syscall\n" \ - ); - -/* The return code for realtime-signals. */ -#if _MIPS_SIM != _ABIO32 -# ifdef __NR_rt_sigreturn -RESTORE (restore_rt, __NR_rt_sigreturn) -# endif -# ifdef __NR_sigreturn -RESTORE (restore, __NR_sigreturn) -# endif -#endif diff --git a/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h new file mode 100644 index 0000000..4ada322 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h @@ -0,0 +1,8 @@ +/* NIOS2 uses the generic Linux UAPI but defines SA_RESTORER. */ +#define SA_RESTORER 0x04000000 +#include + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h new file mode 100644 index 0000000..c5213f2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h @@ -0,0 +1,8 @@ +/* powerpc kernel sigaction is similar to generic Linux UAPI one. */ +#define SA_RESTORER 0x04000000 +#include + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h b/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h new file mode 100644 index 0000000..a8beaf7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h @@ -0,0 +1,28 @@ +#include + +#define SA_RESTORER 0x04000000 + +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + union + { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, siginfo_t *, void *); + } _u; +#define k_sa_handler _u._sa_handler +#ifndef __s390x__ + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +#else + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; +#endif +}; + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c b/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c deleted file mode 100644 index c13927c..0000000 --- a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 2001-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -/* 64 bit Linux for S/390 only has rt signals, thus we do not even want to try - falling back to the old style signals as the default Linux handler does. */ - -#include -#include -#include - -#include -#include - -/* The variable is shared between all wrappers around signal handling - functions which have RT equivalents. This is the definition. */ - - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - return INLINE_SYSCALL (rt_sigaction, 4, sig, act, oact, _NSIG / 8); -} -libc_hidden_def (__libc_sigaction) - -#include diff --git a/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h new file mode 100644 index 0000000..7ebcd08 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h @@ -0,0 +1,8 @@ +/* SH uses the generic Linux UAPI but defines SA_RESTORER. */ +#define SA_RESTORER 0x04000000 +#include + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/sigaction.c b/sysdeps/unix/sysv/linux/sigaction.c index 40a311a..0e6851a 100644 --- a/sysdeps/unix/sysv/linux/sigaction.c +++ b/sysdeps/unix/sysv/linux/sigaction.c @@ -22,11 +22,19 @@ #include #include -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ +/* New ports should not define the obsolete SA_RESTORER, however some + architecture requires for compat mode and/or due old ABI. */ #include +#ifndef SA_RESTORER +# define SET_SA_RESTORER(kact, act) +# define RESET_SA_RESTORER(act, kact) +#endif + +/* SPARC passes the restore function as an argument to rt_sigaction. */ +#ifndef STUB +# define STUB(act) +#endif /* If ACT is not NULL, change the action for SIG to *ACT. If OACT is not NULL, put the old action for SIG in *OACT. */ @@ -42,25 +50,21 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) kact.k_sa_handler = act->sa_handler; memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER - kact.sa_restorer = act->sa_restorer; -#endif + SET_SA_RESTORER (&kact, act); } /* XXX The size argument hopefully will have to be changed to the real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); + result = INLINE_SYSCALL_CALL (rt_sigaction, sig, + act ? &kact : NULL, + oact ? &koact : NULL, STUB(act) _NSIG / 8); if (oact && result >= 0) { oact->sa_handler = koact.k_sa_handler; memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif + RESET_SA_RESTORER (oact, &koact); } return result; } diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h new file mode 100644 index 0000000..bee7e9c --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h @@ -0,0 +1,10 @@ +/* SPARC 'struct __new_sigaction' is similar to generic Linux UAPI with + a sa_restorer field, even though function is passed as an argument + to rt_sigaction syscall. */ +#define SA_RESTORER 0x04000000 +#include + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = NULL +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c index 204a5d8..c1d8f45 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c @@ -27,43 +27,12 @@ static void __rt_sigreturn_stub (void); static void __sigreturn_stub (void); -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - struct kernel_sigaction kact, koact; - unsigned long stub = 0; - int ret; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - if (((kact.sa_flags = act->sa_flags) & SA_SIGINFO) != 0) - stub = (unsigned long) &__rt_sigreturn_stub; - else - stub = (unsigned long) &__sigreturn_stub; - stub -= 8; - kact.sa_restorer = NULL; - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - ret = INLINE_SYSCALL (rt_sigaction, 5, sig, act ? &kact : 0, - oact ? &koact : 0, stub, _NSIG / 8); - - if (oact && ret >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - return ret; -} -libc_hidden_def (__libc_sigaction) - -#include +#define STUB(act) \ + ((unsigned long)((act->sa_flags & SA_SIGINFO) \ + ? &__rt_sigreturn_stub \ + : &__sigreturn_stub) - 8), +#include static inhibit_stack_protector diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c index 73cda4c..cfbbc6e 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c @@ -21,50 +21,13 @@ #include #include #include -#include -#include - -#include - -/* SPARC 64bit userland requires a kernel that has rt signals anyway. */ static void __rt_sigreturn_stub (void); -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int ret; - struct kernel_sigaction kact, koact; - unsigned long stub = ((unsigned long) &__rt_sigreturn_stub) - 8; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags; - kact.sa_restorer = NULL; - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - ret = INLINE_SYSCALL (rt_sigaction, 5, sig, - act ? &kact : 0, - oact ? &koact : 0, stub, _NSIG / 8); - - if (oact && ret >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - - return ret; -} -libc_hidden_def (__libc_sigaction) - -#include +#define STUB(act) \ + (((unsigned long) &__rt_sigreturn_stub) - 8), +#include static inhibit_stack_protector diff --git a/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h b/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h new file mode 100644 index 0000000..a943d52 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h @@ -0,0 +1,9 @@ +/* tile kernel sigaction is similar to generic Linux UAPI one + and SA_RESTORER is used only for binary compatibility. */ +#define SA_RESTORER 0x04000000 +#include + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c index 2f7459f..4e6d9cc 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c +++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c @@ -16,65 +16,20 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include #include -#include - -#include -#include - -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include - -#include "ucontext_i.h" - -/* We do not globally define the SA_RESTORER flag so do it here. */ #define SA_RESTORER 0x04000000 +#include -/* Using the hidden attribute here does not change the code but it - helps to avoid warnings. */ extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \ + (kact)->sa_restorer = &restore_rt -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags | SA_RESTORER; - - kact.sa_restorer = &restore_rt; - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, - sig, act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - return result; -} -libc_hidden_def (__libc_sigaction) - -#include +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer +#include /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to @@ -93,6 +48,8 @@ libc_hidden_def (__libc_sigaction) a bit tricky. We don't use the gas cfi directives, so that we can reliably add .cfi_signal_frame. */ +#include "ucontext_i.h" + #define do_cfa_expr \ " .byte 0x0f\n" /* DW_CFA_def_cfa_expression */ \ " .uleb128 2f-1f\n" /* length */ \ From patchwork Mon Feb 12 12:42:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 128032 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3176179ljc; Mon, 12 Feb 2018 04:49:19 -0800 (PST) X-Google-Smtp-Source: AH8x226YgJyUy6dAOWR1CPTXqs+ZfeFpIu2wOi+r4gGfOp7sKCRSbXlpFmMQZok9zJ/osbTiF3+E X-Received: by 2002:a17:902:5854:: with SMTP id f20-v6mr6597392plj.374.1518439759642; Mon, 12 Feb 2018 04:49:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518439759; cv=none; d=google.com; s=arc-20160816; b=UhWtmEXkLwPR9hXTqN7dMsYhADKzAa3X2+uwdgfbt98Odj1+UpagLwE2IqNc4916P8 DmaZWpsRNRShUh5YL+LByeXmJuRWZHIdJ+YVFP8jL2VJLG1mWwraMmtkDwi4q18T3IeC YXNai7TY9hsy3N+8ERsMIJ8POcQdaEo0i4GKFgvAzYqEiyValDbk0QMpi4MMhbPr1zj3 LSaa1S8EKH34gRG4HtuMA9S0qdIkzDYyhgkz/swUqEJZ8ReXN28NMZOnmKnGMwg4oTUX HbPCn8yKK02S0ApnuYVXTBoBWxdCdF48CiPX906kjeHwmeDZ1ZofG9JCApBuClAJdH23 ql9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=70dswwT2acrztGtM4lQWP/nyF82j1PsDXLJyBh27544=; b=bhOiOoeojcWqOy4ibeCoPBqHmcBsy2cf6EB6aPF1pCiDM1Y0AxxKhRhCd1lXkXg/Km jr2h6gCqFR16uVIc32dJsqGBo0frMUvBdo30p1Mc5MSMUAUyPFj89sZ1K03BEOwehX3Z 4PV4YR1OPO4rO5j+99YE2C3fR5+TDrB7HoSPN0eK0DHEkC7crsKBgMXANWau4nE1r+EY pD232USEuFRQJK+fMYM6DIGzYp/rlc1RnpM1ajE7xaTzo1nL6KQ5YMzluV+NIdcXs3qk Gi2wnuc6+aBFF4qOoTG8+Au8e4bxx8GmcmqGn5v5lZl3Jj/YhNhbRwgpCxhDKNpRbGAU Dnag== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=cSeqO2dJ; spf=pass (google.com: domain of libc-alpha-return-90260-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90260-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id j88si6293111pfj.145.2018.02.12.04.49.19 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Feb 2018 04:49:19 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-90260-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=cSeqO2dJ; spf=pass (google.com: domain of libc-alpha-return-90260-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90260-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=IMwHJqtBQtxYYQCv5/IPf4QvwNo4ov1 9a0DhRnWOKSd4wZDoST7gEH85PWg/pUFusr3ErImI/w6qMqgOFeCYrEbSJvIPHzh 6XLfE9Upu0V02Pq4zw/aETUy9seov6q5cnea2nyUuoVCNOShdzJsqDcK3bzVepHx 6RG0sSkZJ6dY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=/i52dxwAfxFen/kzhA4h2wdlE9c=; b=cSeqO 2dJerYsIQafGTRYcRLZ0A2sM8GseCvTpCttptIfnuX6yA+VjpQnxfbwofTKSbN3A 8oRxgZEIt0A/LzEgiQsmImz91OIFLQEhyOubEegK+gmhyezn7qjl1At/ED/NmPX4 S5axqHIiQxMEFi4bCyiRT8rPqRjG2CvADTum20= Received: (qmail 82044 invoked by alias); 12 Feb 2018 12:49:00 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 81918 invoked by uid 89); 12 Feb 2018 12:48:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=Fire, faults X-HELO: mail-qt0-f194.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=70dswwT2acrztGtM4lQWP/nyF82j1PsDXLJyBh27544=; b=bVPyEqulFamowigi2wWPbhYLvUgEjGHhwjLmYp0OZ5rVtwsY3dw3ElEeTz+YHxgTzt 2jSI9X9wdLZ216bLWLXJgHEuK9Ns6RbZR95B6MNUSYqDuULP08plDA1X5S42rCjlodv2 dYyq16CVslTxges4S1fhLkbwHuDBkb8nsHf+WqI5OlFlf4SZstrLtTBmPBWTZg8ETZZI m8HiR5HuKQWPhXEaWNc/XEId624M8D6HVgIUmB1yf7e1PrLoYkmkJwDL2k5gxGXH4scA cx/frPp251Fd9juP0byuCdp3no9ldRokTu18AEs06ZoJcGQ/jujNeZGVAaKkrR822aLk ireQ== X-Gm-Message-State: APf1xPBsPanCNtuhfxRQSDloJU3u8MOs4F7DMZcofDfcR0DUtnfulLdJ 2Uk9peDq1/mFAuh7MxeycMGFOp1oGgU= X-Received: by 10.200.97.86 with SMTP id d22mr18205977qtm.217.1518439355560; Mon, 12 Feb 2018 04:42:35 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v4 4/4] i386: Fix i386 sigaction sa_restorer initialization (BZ#21269) Date: Mon, 12 Feb 2018 10:42:25 -0200 Message-Id: <1518439345-6013-4-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1518439345-6013-1-git-send-email-adhemerval.zanella@linaro.org> References: <1518439345-6013-1-git-send-email-adhemerval.zanella@linaro.org> This patch fixes the i386 sa_restorer field initialization for sigaction syscall for kernel with vDSO. As described in bug report, x86_32 Linux (and compat on x86_64) interprets SA_RESTORER clear with nonzero sa_restorer as a request for stack switching if the SS segment is 'funny' This means that anything that tries to mix glibc's signal handling with segmentation (for instance through modify_ldt syscall) is randomly broken depending on what values lands in sa_restorer. The testcase added is based on Linux test tools/testing/selftests/x86/ldt_gdt.c, more specifically in do_multicpu_tests function. The main changes are: - C11 atomics instead of plain access. - Remove x86_64 support which simplifies the syscall handling and fallbacks. - Replicate only the test required to trigger the issue. (I added some comments of my understanding of how the testcase is triggering the issue, so if someone with more x86 knowledge could check if I get this right I will be grateful) Checked on i686-linux-gnu. [BZ #21269] * sysdeps/unix/sysv/linux/i386/Makefile (tests): Add tst-bz21269. * sysdeps/unix/sysv/linux/i386/sigaction.c (SET_SA_RESTORER): Clear sa_restorer for vDSO case. * sysdeps/unix/sysv/linux/i386/tst-bz21269.c: New file. Signed-off-by: Adhemerval Zanella --- ChangeLog | 6 + sysdeps/unix/sysv/linux/i386/Makefile | 3 + sysdeps/unix/sysv/linux/i386/sigaction.c | 2 + sysdeps/unix/sysv/linux/i386/tst-bz21269.c | 233 +++++++++++++++++++++++++++++ 4 files changed, 244 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/i386/tst-bz21269.c -- 2.7.4 diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile index 4080b8c..da716e2 100644 --- a/sysdeps/unix/sysv/linux/i386/Makefile +++ b/sysdeps/unix/sysv/linux/i386/Makefile @@ -3,6 +3,9 @@ default-abi := 32 ifeq ($(subdir),misc) sysdep_routines += ioperm iopl vm86 + +tests += tst-bz21269 +$(objpfx)tst-bz21269: $(shared-thread-library) endif ifeq ($(subdir),elf) diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c index 137c73b..df9fa0c 100644 --- a/sysdeps/unix/sysv/linux/i386/sigaction.c +++ b/sysdeps/unix/sysv/linux/i386/sigaction.c @@ -32,6 +32,8 @@ extern void restore (void) asm ("__restore") attribute_hidden; (kact)->sa_restorer = (((act)->sa_flags & SA_SIGINFO) \ ? &restore_rt : &restore); \ } \ + else \ + (kact)->sa_restorer = NULL; \ }) #define RESET_SA_RESTORER(act, kact) \ diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c new file mode 100644 index 0000000..353e365 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c @@ -0,0 +1,233 @@ +/* Test for i386 sigaction sa_restorer handling (BZ#21269) + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* This is based on Linux test tools/testing/selftests/x86/ldt_gdt.c, + more specifically in do_multicpu_tests function. The main changes + are: + + - C11 atomics instead of plain access. + - Remove x86_64 support which simplifies the syscall handling + and fallbacks. + - Replicate only the test required to trigger the issue for the + BZ#21269. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +static int +xset_thread_area (struct user_desc *u_info) +{ + long ret = syscall (SYS_set_thread_area, u_info); + TEST_VERIFY_EXIT (ret == 0); + return ret; +} + +static void +xmodify_ldt (int func, const void *ptr, unsigned long bytecount) +{ + TEST_VERIFY_EXIT (syscall (SYS_modify_ldt, 1, ptr, bytecount) == 0); +} + +static int +futex (int *uaddr, int futex_op, int val, void *timeout, int *uaddr2, + int val3) +{ + return syscall (SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3); +} + +static void +xsethandler (int sig, void (*handler)(int, siginfo_t *, void *), int flags) +{ + struct sigaction sa = { 0 }; + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO | flags; + TEST_VERIFY_EXIT (sigemptyset (&sa.sa_mask) == 0); + TEST_VERIFY_EXIT (sigaction (sig, &sa, 0) == 0); +} + +static jmp_buf jmpbuf; + +static void +sigsegv_handler (int sig, siginfo_t *info, void *ctx_void) +{ + siglongjmp (jmpbuf, 1); +} + +/* Points to an array of 1024 ints, each holding its own index. */ +static const unsigned int *counter_page; +static struct user_desc *low_user_desc; +static struct user_desc *low_user_desc_clear; /* Used to delete GDT entry. */ +static int gdt_entry_num; + +static void +setup_counter_page (void) +{ + long page_size = sysconf (_SC_PAGE_SIZE); + TEST_VERIFY_EXIT (page_size > 0); + unsigned int *page = xmmap (NULL, page_size, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1); + for (int i = 0; i < (page_size / sizeof (unsigned int)); i++) + page[i] = i; + counter_page = page; +} + +static void +setup_low_user_desc (void) +{ + low_user_desc = xmmap (NULL, 2 * sizeof (struct user_desc), + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1); + + low_user_desc->entry_number = -1; + low_user_desc->base_addr = (unsigned long) &counter_page[1]; + low_user_desc->limit = 0xffff; + low_user_desc->seg_32bit = 1; + low_user_desc->contents = 0; + low_user_desc->read_exec_only = 0; + low_user_desc->limit_in_pages = 1; + low_user_desc->seg_not_present = 0; + low_user_desc->useable = 0; + + xset_thread_area (low_user_desc); + + low_user_desc_clear = low_user_desc + 1; + low_user_desc_clear->entry_number = gdt_entry_num; + low_user_desc_clear->read_exec_only = 1; + low_user_desc_clear->seg_not_present = 1; +} + +/* Possible values of futex: + 0: thread is idle. + 1: thread armed. + 2: thread should clear LDT entry 0. + 3: thread should exit. */ +static atomic_uint ftx; + +static void * +threadproc (void *ctx) +{ + while (1) + { + futex ((int *) &ftx, FUTEX_WAIT, 1, NULL, NULL, 0); + while (atomic_load (&ftx) != 2) + { + if (atomic_load (&ftx) >= 3) + return NULL; + } + + /* clear LDT entry 0. */ + const struct user_desc desc = { 0 }; + xmodify_ldt (1, &desc, sizeof (desc)); + + /* If ftx == 2, set it to zero, If ftx == 100, quit. */ + if (atomic_fetch_add (&ftx, -2) != 2) + return NULL; + } +} + + +/* As described in testcase, for historical reasons x86_32 Linux (and compat + on x86_64) interprets SA_RESTORER clear with nonzero sa_restorer as a + request for stack switching if the SS segment is 'funny' (this is default + scenario for vDSO system). This means that anything that tries to mix + signal handling with segmentation should explicit clear the sa_restorer. + + This testcase check if sigaction in fact does it by changing the local + descriptor table (LDT) through the modify_ldt syscall and triggering + a synchronous segfault on iret fault by trying to install an invalid + segment. With a correct zeroed sa_restorer it should not trigger an + 'real' SEGSEGV and allows the siglongjmp in signal handler. */ + +static int +do_test (void) +{ + setup_counter_page (); + setup_low_user_desc (); + + pthread_t thread; + unsigned short orig_ss; + + xsethandler (SIGSEGV, sigsegv_handler, 0); + /* 32-bit kernels send SIGILL instead of SIGSEGV on IRET faults. */ + xsethandler (SIGILL, sigsegv_handler, 0); + + thread = xpthread_create (0, threadproc, 0); + + asm volatile ("mov %%ss, %0" : "=rm" (orig_ss)); + + for (int i = 0; i < 5; i++) + { + if (sigsetjmp (jmpbuf, 1) != 0) + continue; + + /* Make sure the thread is ready after the last test. */ + while (atomic_load (&ftx) != 0) + ; + + struct user_desc desc = { + .entry_number = 0, + .base_addr = 0, + .limit = 0xffff, + .seg_32bit = 1, + .contents = 0, + .read_exec_only = 0, + .limit_in_pages = 1, + .seg_not_present = 0, + .useable = 0 + }; + + xmodify_ldt (0x11, &desc, sizeof (desc)); + + /* Arm the thread. */ + ftx = 1; + futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + + asm volatile ("mov %0, %%ss" : : "r" (0x7)); + + /* Fire up thread modify_ldt call. */ + atomic_store (&ftx, 2); + + while (atomic_load (&ftx) != 0) + ; + + /* On success, modify_ldt will segfault us synchronously and we will + escape via siglongjmp. */ + support_record_failure (); + } + + atomic_store (&ftx, 100); + futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + + xpthread_join (thread); + + return 0; +} + +#include