From patchwork Mon Apr 10 20:46:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 67589 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7BD53385380E for ; Mon, 10 Apr 2023 20:48:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7BD53385380E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1681159695; bh=n7wxa6s7iaJNdj/idNrqx354NeTtAmAHFFfdpcN8hwM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=VDBqFTgvPVE4fYHW4Sc/66MuxDopXAS22B8eiYEJoX8u2LB3Sl1RINIk/gUFBIiqf QDAGNhcD6X2VihZUcCIZ/M6LiiVPyHe4ADHu9fLzDp90w/gGZU85CEQr7XSNMAQhdV nxoDEQrdU+lKUPnZgyD6+HaZNgq8y2ZNebA+9HkI= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-oi1-x234.google.com (mail-oi1-x234.google.com [IPv6:2607:f8b0:4864:20::234]) by sourceware.org (Postfix) with ESMTPS id 610BE3858C5E for ; Mon, 10 Apr 2023 20:46:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 610BE3858C5E Received: by mail-oi1-x234.google.com with SMTP id w19so4030099oiv.13 for ; Mon, 10 Apr 2023 13:46:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681159587; x=1683751587; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=n7wxa6s7iaJNdj/idNrqx354NeTtAmAHFFfdpcN8hwM=; b=XQ6RmbDSZDQe9yl8Lb7Z15h5fZNm0ZYwDnC3jkZuLhlq8YVY83DnchG19djr4GWm+v CjIaStqa4hr9h7/RgSfFgUKgADMsgF2Wa1Hviy57w2alpyqjjVBtYf1ncIHyKh7LkUFl 0pplQtlQWZuA1vRxm1k6cspJtN0f6C32GuB6+zbRds5lcUKb66c5AE2UsSFrVGblUwCA NIEqsWT+fkDppN5RVEGMBIsUS2AiicgIuNjyCPSpqPY4zMpnHKVibpgUr0u3/hlt4omf SmO8A4ihxCp569y62fOmJniyVruJlLUF7Fra9Ca8ZRuDNw9hPzf/pso8RyG80GS09r7D 7psw== X-Gm-Message-State: AAQBX9cLxq6Euti7UzANi60kwVgid13TQAa8hAutYKkRFEx3gBfXkWEX Zg/SHbfLjlqwG+cVaT8j/nzMBzi93XJfFdJ8Ao7IkA== X-Google-Smtp-Source: AKy350ZBeQsvbodoSnIIc8vNE/U3SkyhKzTdtgglSNlclOULDTnPJANTWR3+tCdZT9+v8kdcrb8TnQ== X-Received: by 2002:a05:6808:2002:b0:389:92d0:c073 with SMTP id q2-20020a056808200200b0038992d0c073mr7093829oiw.23.1681159585567; Mon, 10 Apr 2023 13:46:25 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:55a1:d59a:609a:284:6ed]) by smtp.gmail.com with ESMTPSA id p5-20020acabf05000000b003896f132821sm4865732oif.41.2023.04.10.13.46.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Apr 2023 13:46:24 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v5 12/22] ia64: Fix Race conditions in pthread cancellation [BZ#12683] Date: Mon, 10 Apr 2023 17:46:04 -0300 Message-Id: <20230410204614.4129551-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230410204614.4129551-1-adhemerval.zanella@linaro.org> References: <20230410195907.4123869-1-adhemerval.zanella@linaro.org> <20230410204614.4129551-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" 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. Checked on ia64-linux-gnu. --- .../sysv/linux/ia64/cancellation-pc-check.h | 48 +++++++++++ sysdeps/unix/sysv/linux/ia64/syscall_cancel.S | 81 +++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h create mode 100644 sysdeps/unix/sysv/linux/ia64/syscall_cancel.S 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..24f05f9759 --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h @@ -0,0 +1,48 @@ +/* Architecture specific bits for cancellation handling. + Copyright (C) 2023 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 +cancellation_pc_check (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/syscall_cancel.S b/sysdeps/unix/sysv/linux/ia64/syscall_cancel.S new file mode 100644 index 0000000000..732bf60185 --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/syscall_cancel.S @@ -0,0 +1,81 @@ +/* Cancellable syscall wrapper. Linux/IA64 version. + Copyright (C) 2023 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 +#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 +__syscall_cancel_arch_start: + ;; + .mmi + nop 0 + ld4.acq r14=[r32] + nop 0 + ;; + .mib + nop 0 + tbit.z p6, p7=r14, TCB_CANCELED_BIT + .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 +__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)