From patchwork Mon Oct 14 20:56:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 176340 Delivered-To: patch@linaro.org Received: by 2002:a92:7e96:0:0:0:0:0 with SMTP id q22csp5011856ill; Mon, 14 Oct 2019 13:58:02 -0700 (PDT) X-Google-Smtp-Source: APXvYqxnqpuyFR/Dc8CanJsNdFlidukIRCcDJE10miWAeEHevQBJI3Gwss40+5SPWwNvyTcBGNi6 X-Received: by 2002:a17:906:470d:: with SMTP id y13mr30661950ejq.241.1571086681951; Mon, 14 Oct 2019 13:58:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571086681; cv=none; d=google.com; s=arc-20160816; b=a7vbCbnhUps6wcbACS5ylZlCGauAF1lE4DPpKXIWTi/FSx4TI7T99CnNnDWbWvuWYo 7mE0ofDPybzXLavShjVHx0u63fxwGmdp5vkZLUJ0y6DQP2uEvEEZ7VsTZoqJh9OTtEgn 5ot4IBxSri6o19Jg+kUV4i+rXHRz/vASOegU7AuuUPUabWyiics/cwKBVNwNk0JPKUmG 5gpeIF309lkqi38EnwA9NOgU3vvbbro/wsU7zZWg4StQQrQG47pJyzqM0yzWNqB+59B4 Vcw/NaBIZdGv255WooolnqTg5Z1t8lG0Zm45GZxn/AiSZpf0nxhcc5hWTGnDz4kwHw// rXGQ== 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 :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=bv3HGD5sMtMH6meOlXVPd/EuZwt1B0r43f/0HZSpKUk=; b=wIMhkXKrHMlb3qilZkdN5FmA8LTTuSSB3J+GduUlvNpWhCmn62fZl9wsKj6knrGcjo mxHA8gSWpM41Cwj7YfBiFe1q2AgeKgN0yEwRI4lmZvj9IAzWFf1ETNk+vWpQ/nV1xIh+ yjyjF4wFyYD7+VOf4z4oDDAVC65GDfpz6hJzQ6IYsFXgyyXx/UxOmG0SECghzYlc0aAF XOVo0zEWQUOWWCaypIiSwZcCvp0Y7DNGhbaOEdRtjvu4kl+hRmWtnbCdoG011p6oim2V KuhSQQ2dDoJ+6RzguUVLHYs00+/G30REr5MKozfF1CHfsCYs1Z//qHbu+I7/vbid7Vij mFZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=ZwsNWvWr; dkim=pass header.i=@linaro.org header.s=google header.b=N5Rw02zQ; spf=pass (google.com: domain of libc-alpha-return-105931-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-105931-patch=linaro.org@sourceware.org"; dmarc=pass (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 gh12si11362980ejb.191.2019.10.14.13.58.01 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 14 Oct 2019 13:58:01 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-105931-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=ZwsNWvWr; dkim=pass header.i=@linaro.org header.s=google header.b=N5Rw02zQ; spf=pass (google.com: domain of libc-alpha-return-105931-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-105931-patch=linaro.org@sourceware.org"; dmarc=pass (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=nFnVtG/3BgZSH+KfSswqEmJfQMrIy1u Gm8Jmx1FZm7F/2cwBB1CCoHVFS9FXGI/Jh4Jz1Lqyd9HJXjl7xGtTaGN9AMXIc8s 3iP9BxfIMYa64lBE5njYGtJQtazJPX8no7BAocDM79iI9vrbpiLzOpC7NdWZ9ymc oVIYPdTmoLUI= 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=MVg+ySpRqTnCqX9lTsueIwIMirk=; b=ZwsNW vWrm7w7/t+aIoFSI5/ghkz7QcMkjB6I9/ujS+oEMWVOjc3wgBrv8IbGBQhWrdfBE Z29XTtfW8EqpcS9KS84ebzQRfTIzspjxsz8IA6D5vDDRZxCV+ettLltPtjjBB9GV xWjZC9wp0NS3i0SBfkAGhLh9gvbi3EG0hyvycQ= Received: (qmail 114119 invoked by alias); 14 Oct 2019 20:57:17 -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 114023 invoked by uid 89); 14 Oct 2019 20:57:17 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.2 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.1 spammy=Due, obtained X-HELO: mail-qt1-f194.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=bv3HGD5sMtMH6meOlXVPd/EuZwt1B0r43f/0HZSpKUk=; b=N5Rw02zQg0YjdMc4haWn0gpvxHtMVu1b0EMmZu0t2tXRG8EmPqEsDwUtOubIiW33dw zTzeixCUBcrdNnwrK9JtJmS2rcxDdJliLkW8oQ2ZNqmrY2974ArgsMWOMjGtVMtHjg6n NJcsYtzClU2vWzBLjEgaWcvVPGufyGzbec2VNyVkwLR6X+iY3LYNC4ab9UqAAFYXpkoS Y3wXTAqK4wcMBXj9073u2COhjGYY7X+fSZubniU5WvpuR8QBzhxaM7wmrM0XQcNGPR5X U/L5PUrbYI8w+X1B3PBDxi6PbufIxcoWFvRbS9EMF8gPfSyLY6d0CAF/xkbfXgLh5IBI mWbg== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v3 05/21] nptl: ia64: Fix Race conditions in pthread cancellation (BZ#12683) Date: Mon, 14 Oct 2019 17:56:40 -0300 Message-Id: <20191014205656.29834-6-adhemerval.zanella@linaro.org> In-Reply-To: <20191014205656.29834-1-adhemerval.zanella@linaro.org> References: <20191014205656.29834-1-adhemerval.zanella@linaro.org> This patch adds the ia64 modifications required for the BZ#12683 fix. The syscall bridge uses the old brk 0x10000 instruction because by using the vDSO gate the resulting PC value for an interrupted syscall points to an address outside the expected markers in __syscall_cancel_arch. This is similar to i686 issue. Also the __syscall_cancel_arch issues the 'break 0x100000' on its own bundle, and __syscall_cancel_arch_end points to end of the previous one. It requires an arch-specific ucontext_check_pc_boundary to check for the ri value (embedded in the sc_ip by the kernel) to check if the syscall had any side-effects. Also, ia64 issues a sigcontext as third argument for sigaction handler with SA_SIGINFO which requires an arch-specific ucontext_add_cancel. Checked on ia64-linux-gnu. --- .../sysv/linux/ia64/cancellation-pc-check.h | 48 +++++++++++ .../sysv/linux/ia64/cancellation-sigmask.h | 33 ++++++++ sysdeps/unix/sysv/linux/ia64/syscall_cancel.S | 83 +++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h create mode 100644 sysdeps/unix/sysv/linux/ia64/cancellation-sigmask.h create mode 100644 sysdeps/unix/sysv/linux/ia64/syscall_cancel.S -- 2.17.1 diff --git a/sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h b/sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h new file mode 100644 index 0000000000..bbd0c99fe1 --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h @@ -0,0 +1,48 @@ +/* Architecture specific bits for cancellation handling. + Copyright (C) 2019 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 + . */ + +#ifndef _NPTL_CANCELLATION_PC_CHECK +#define _NPTL_CANCELLATION_PC_CHECK 1 + +/* Check if the program counter (PC) from ucontext CTX is within the start and + then end boundary from the __syscall_cancel_arch bridge. Return TRUE if + the PC is within the boundary, meaning the syscall does not have any side + effects; or FALSE otherwise. */ +static bool +ucontext_check_pc_boundary (void *ctx) +{ + /* Both are defined in syscall_cancel.S for each architecture. */ + extern const char __syscall_cancel_arch_start[1]; + extern const char __syscall_cancel_arch_end[1]; + + uintptr_t sc_ip = ((struct sigcontext *) (ctx))->sc_ip; + uintptr_t cr_iip = sc_ip & ~0x3ull; + uintptr_t ri = sc_ip & 0x3ull; + + /* IA64 __syscall_cancel_arch issues the 'break 0x100000' on its own bundle, + and __syscall_cancel_arch_end points to end of the previous bundle. + To check if the syscall had any side-effects we need to check the slot + number. */ + if (cr_iip == (uintptr_t) __syscall_cancel_arch_end) + return ri == 0; + + return cr_iip >= (uintptr_t) __syscall_cancel_arch_start + && cr_iip < (uintptr_t) __syscall_cancel_arch_end; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/ia64/cancellation-sigmask.h b/sysdeps/unix/sysv/linux/ia64/cancellation-sigmask.h new file mode 100644 index 0000000000..300f090a82 --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/cancellation-sigmask.h @@ -0,0 +1,33 @@ +/* Architecture specific bits for cancellation handling. + Copyright (C) 2019 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 + . */ + +#ifndef _NPTL_CANCELLATION_SIGMASK_H +#define _NPTL_CANCELLATION_SIGMASK_H 1 + +/* Add the SIGCANCEL signal on sigmask set at the ucontext CTX obtained from + the sigaction handler. */ +static void +ucontext_add_cancel (void *ctx) +{ + /* IA64 issues a sigcontext as third argument for sigaction handler (instead + of usual ucontext_t). */ + struct sigcontext *sctx = (struct sigcontext *) (ctx); + __sigaddset ((sigset_t *) &sctx->sc_mask, SIGCANCEL); +} + +#endif diff --git a/sysdeps/unix/sysv/linux/ia64/syscall_cancel.S b/sysdeps/unix/sysv/linux/ia64/syscall_cancel.S new file mode 100644 index 0000000000..bf6ec105db --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/syscall_cancel.S @@ -0,0 +1,83 @@ +/* Cancellable syscall wrapper. Linux/IA64 version. + Copyright (C) 2019 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 +#undef ret + +/* long int __syscall_cancel_arch (int *cancelhandling, long int nr, + long int arg1, long int arg2, long int arg3, + long int arg4, long int arg5, long int arg6) +*/ + +ENTRY (__syscall_cancel_arch) + .prologue ASM_UNW_PRLG_RP | ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE (8) + .mmi + .save ar.pfs, r41 + alloc r41=ar.pfs,8,3,8,0 + mov r15=r33 + .save rp, r40 + mov r40=b0 + .body + .mmi + mov r43=r34 + mov r44=r35 + mov r45=r36 + ;; + .mmi + mov r46=r37 + mov r47=r38 + mov r48=r39 + ;; + + .global __syscall_cancel_arch_start + .type __syscall_cancel_arch_start,@function +__syscall_cancel_arch_start: + ;; + .mmi + nop 0 + ld4.acq r14=[r32] + nop 0 + ;; + .mib + nop 0 + tbit.z p6, p7=r14, 2 + .pred.safe_across_calls p1-p63 +(p7) br.call.dpnt.many b0 = __syscall_do_cancel# + .pred.safe_across_calls p1-p5,p16-p63 + ;; + + /* Due instruction bundle ia64 has the end marker before the syscall + instruction. Check IA64 ucontext_check_pc_boundary on how the PC + is checked. */ + .global __syscall_cancel_arch_end + .type __syscall_cancel_arch_end,@function +__syscall_cancel_arch_end: + break 0x100000 + ;; + .mmi + cmp.ne p6, p7=-1, r10 + nop 0 + mov b0=r40 + ;; + .mib +(p7) sub r8=r0, r8 + mov ar.pfs=r41 + br.ret.sptk.many b0 + +END (__syscall_cancel_arch) +libc_hidden_def (__syscall_cancel_arch)