From patchwork Wed Jun 3 00:04:32 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 136340 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 764A34BA2E2C for ; Wed, 3 Jun 2026 00:13:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 764A34BA2E2C Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=KMNJb+G+ X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-yw1-x1129.google.com (mail-yw1-x1129.google.com [IPv6:2607:f8b0:4864:20::1129]) by sourceware.org (Postfix) with ESMTPS id 8E67E4BA2E24 for ; Wed, 3 Jun 2026 00:07:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8E67E4BA2E24 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 8E67E4BA2E24 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1129 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445225; cv=none; b=aU0U/vsfq84GV0Gpmlt6+Y5/7sDqHjJUc4A9hXJGO0YDntBaR+vmxhW5ZvqbsoXtNTIddxX/HrZZyYVhjzEWsLk4Tge/d/wdFm7VOYAi42ZqCKHPV9x6h0wjQzKsB27CEU2zCv9fSBGBKkB5kFxooAVYu1FcGLI3o2v5eI/GupU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445225; c=relaxed/simple; bh=hS/Dh+6ew+vM1b0sUOyHG/C1EXyyCg9cVg+le/cKGYY=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=JiESHRT/m11kDVc/Yv5WT406rbuEFMQ1wQHCJbckpKRq7VbQB8zytsfpvPtS0bwUsaNXex1bJwLXbtoXNx3Y5KepyBLwXfOD4NMBe0uHVAK/mZx+TquukWqAomMerjcGakAdD3Pq9f+Usl6rrwaDLqbNqtzpUNaQD5CujhPAd78= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=KMNJb+G+ DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8E67E4BA2E24 Received: by mail-yw1-x1129.google.com with SMTP id 00721157ae682-7dca5a81be2so58934127b3.2 for ; Tue, 02 Jun 2026 17:07:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1780445225; x=1781050025; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=E0pOrCnJGqny7iPZLN9pAOcdvCmBRD3NPYUeDpXGMg8=; b=KMNJb+G+M6zYw35SeYQctzFIaK+MiqZOn2CLQ+1jX3VuDRc1yf9wx069c4vjcGmXTT 8I1KDe94+SDjfK460VmY5S9wFxZolTxdaZL+MZH56pFJLCmyTX5wAouwCnHHi67feuW1 RgH4vapmMTaq1LjQYEeuplVfzw6JgNA0m+WlfCWemNZy/Jh02auNEWM2hTW3eZF4gx0l K5LSvKC6MzPflY/muAGko1olHsr/giX34jGb5MSBUrfTPeeWCPC4XlsmwAPuxMl06CpG otmOWj9ctLifb7QyIY2lEzi+FEtyHM1Klr7HzQAM0S6qtBZulMfU9X8ybqclfsRpDaPH 2dOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780445225; x=1781050025; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=E0pOrCnJGqny7iPZLN9pAOcdvCmBRD3NPYUeDpXGMg8=; b=ip4KYxHP3IqUMCBfwviPMM3nvMGTGd+ClOqDjlTKUcMIo48HdfJT6NftVBHQHXUc0I koDGFqPtbq1zFy917aEkV/xIWkb7Vo0KxX8h8uVQ04FC6xXVp9+Nkl7pkEDUresQ7sRw Dmg0kUmV771xkk8te61e2+h1gDmppuDJvI6lYEB6ao4SUv0dIoLoCT1pq1rZkw3foBFx de9x3V1o0Op3NXUmK4m0zBqx10KlTWQcSavI1ypFRg5kOH7FZtjz97yjByeUjmB7Tkxm 3ZrX8jq7M4UYeYtYUHXyJJM/CmtOhb24wKRzmb2G42wyQFrf88u9mD20AorTgjY6VMeE TGMQ== X-Gm-Message-State: AOJu0YzGKAHf7+COjI9fvd5+HDpxO+fyE1Lk6rq8Y8BGTElRzglpUhoH cborwfpE3sXzLPFNhhmo+0IsT9ckxxwKY6C81YXFM7IBnigyEEC6WpFGB882kd454VT4rfRGcfc bf/Ya X-Gm-Gg: Acq92OEwZZQ8BPLxuf9E5L6VAiMfrBoeQiMQOCx8vrlHQkfbgrSzrL1C5hYt+ON/Y4R YCJJTFhA0CLL7TjYgsDdNMWXBm7z1hEOBpiUjN88Re0cFt7oq53DlOYOvLLSHBYA9hdZG3DK8zC v8LLCLAGxXTxiwiXMl/PCV5NOB0iL5gJ/X0DvVBtNmUXg7nj+myKDOHik4UJRjjqvnSfNdsOK31 YbcSpLeg4egSKJRPccYtv9Xlqj+BJWxcFbebf61zI0pLBD4q2GjeqvPB1Darg9vpAhZYnydjZsm gmURPvZHKXF/HfEWScP/T3nF5oMDMCuKgUzSV19bbs+pOzBNwjlEN32xHMYUxlbyWXSAerGRnj6 SfHZdsCvymolD84JgKNFMsdWcEsHdVLLx0dfB5ZPujyMEcWZU8pQTolJHD5nrS+SGUxt3rWKceX frx23SJ8l8vxCpUzFkV5ZNCLRODp6ka8awRT4DRZo379zzCg== X-Received: by 2002:a05:690c:6001:b0:7bd:73f3:7a8d with SMTP id 00721157ae682-7ea4c1bb51cmr10106627b3.42.1780445224769; Tue, 02 Jun 2026 17:07:04 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:efc6:8f41:550d:2b14:9278]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7ea23a9946bsm7332207b3.37.2026.06.02.17.07.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jun 2026 17:07:04 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Anderson Nascimento , Carlos O'Donell Subject: [PATCH 1/8] elf: Propagate the pointer guard to ld.so loaded via static dlopen (BZ 34196) Date: Tue, 2 Jun 2026 21:04:32 -0300 Message-ID: <20260603000656.3287796-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> References: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org The static-dlopen does not initialize the pointer guard for ABIs that define THREAD_SET_POINTER_GUARD. Besides not properly guard the pointer if a libc.so symbol is called, this can leads to setjmp failures (a jmp_buf set up by the loaded ibc.so.6 cannot be restored by the static program's __longjmp, and vice versa). Seed the just-mapped loader's __pointer_chk_guard from the program's __pointer_chk_guard_local in __rtld_static_init, next to the other runtime values copied there. Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. --- elf/Makefile | 6 +++ elf/rtld_static_init.c | 12 +++++ elf/tst-ptrguard-static-dlopen-mod.c | 29 +++++++++++ elf/tst-ptrguard-static-dlopen.c | 51 +++++++++++++++++++ .../tst-ptrguard-static-dlopen.script | 1 + 5 files changed, 99 insertions(+) create mode 100644 elf/tst-ptrguard-static-dlopen-mod.c create mode 100644 elf/tst-ptrguard-static-dlopen.c create mode 100644 elf/tst-ptrguard-static-dlopen.root/tst-ptrguard-static-dlopen.script diff --git a/elf/Makefile b/elf/Makefile index bdf9a786d54..a940b3045e5 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -270,6 +270,7 @@ tests-static-normal := \ tst-env-setuid-static \ tst-getauxval-static \ tst-linkall-static \ + tst-ptrguard-static-dlopen \ tst-single_threaded-pthread-static \ tst-single_threaded-static \ tst-tls-allocation-failure-static \ @@ -576,6 +577,7 @@ tests-container += \ tst-dlopen-tlsmodid-container \ tst-pldd \ tst-preload-pthread-libc \ + tst-ptrguard-static-dlopen \ tst-rootdir \ # tests-container @@ -1013,6 +1015,7 @@ modules-names += \ tst-null-argv-lib \ tst-p_alignmod-base \ tst-p_alignmod3 \ + tst-ptrguard-static-dlopen-mod \ tst-recursive-tlsmallocmod \ tst-recursive-tlsmod0 \ tst-recursive-tlsmod1 \ @@ -3177,6 +3180,9 @@ $(objpfx)tst-tls21mod.so: $(tst-tls-many-dynamic-modules:%=$(objpfx)%.so) $(objpfx)tst-getauxval-static.out: $(objpfx)tst-auxvalmod.so tst-getauxval-static-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx) +$(objpfx)tst-ptrguard-static-dlopen.out: \ + $(objpfx)tst-ptrguard-static-dlopen-mod.so + $(objpfx)tst-dlmopen-gethostbyname.out: $(objpfx)tst-dlmopen-gethostbyname-mod.so $(objpfx)tst-ro-dynamic: $(objpfx)tst-ro-dynamic-mod.so diff --git a/elf/rtld_static_init.c b/elf/rtld_static_init.c index 04eb1c6fcc4..a428542e57e 100644 --- a/elf/rtld_static_init.c +++ b/elf/rtld_static_init.c @@ -81,5 +81,17 @@ __rtld_static_init (struct link_map *map) dl->_dl_find_object = _dl_find_object; dl->_dl_readonly_area = _dl_readonly_area; +#ifndef THREAD_SET_POINTER_GUARD + extern uintptr_t __pointer_chk_guard_local attribute_hidden; + const ElfW(Sym) *guard_sym + = _dl_lookup_direct (map, "__pointer_chk_guard", + 0x69f99cab, /* dl_new_hash output. */ + "GLIBC_PRIVATE", + 0x0963cf85); /* _dl_elf_hash output. */ + if (guard_sym != NULL) + *(uintptr_t *) DL_SYMBOL_ADDRESS (map, guard_sym) + = __pointer_chk_guard_local; +#endif + __rtld_static_init_arch (map, dl); } diff --git a/elf/tst-ptrguard-static-dlopen-mod.c b/elf/tst-ptrguard-static-dlopen-mod.c new file mode 100644 index 00000000000..1b98e24d038 --- /dev/null +++ b/elf/tst-ptrguard-static-dlopen-mod.c @@ -0,0 +1,29 @@ +/* Shared object for the static-dlopen pointer guard test. + Copyright (C) 2026 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 + +static jmp_buf jb; +void (*do_longjmp) (jmp_buf); + +void +foo (void) +{ + if (setjmp (jb) == 0) + do_longjmp (jb); +} diff --git a/elf/tst-ptrguard-static-dlopen.c b/elf/tst-ptrguard-static-dlopen.c new file mode 100644 index 00000000000..5e4337b11cd --- /dev/null +++ b/elf/tst-ptrguard-static-dlopen.c @@ -0,0 +1,51 @@ +/* Test that the pointer guard is propagated to ld.so via static dlopen. + Copyright (C) 2026 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 + . */ + +/* A statically linked program dlopens a shared object; the object's setjmp + uses the just-mapped libc.so's pointer guard while the longjmp below uses + the program's guard. Unless __rtld_static_init propagates the guard to + the loaded loader the two differ, and the setjmp/longjmp round-trip jumps + to a corrupt address and crashes. */ + +#include +#include +#include + +static void +call_longjmp (jmp_buf jb) +{ + longjmp (jb, 1); +} + +static int +do_test (void) +{ + void *h = xdlopen ("tst-ptrguard-static-dlopen-mod.so", RTLD_NOW); + void (*foo) (void) = xdlsym (h, "foo"); + void (**do_longjmp) (jmp_buf) = xdlsym (h, "do_longjmp"); + *do_longjmp = call_longjmp; + + /* foo () sets the jump buffer and calls back into call_longjmp; a + mismatched guard makes the return jump fault. */ + foo (); + + xdlclose (h); + return 0; +} + +#include diff --git a/elf/tst-ptrguard-static-dlopen.root/tst-ptrguard-static-dlopen.script b/elf/tst-ptrguard-static-dlopen.root/tst-ptrguard-static-dlopen.script new file mode 100644 index 00000000000..e4f49b34754 --- /dev/null +++ b/elf/tst-ptrguard-static-dlopen.root/tst-ptrguard-static-dlopen.script @@ -0,0 +1 @@ +cp $B/elf/tst-ptrguard-static-dlopen-mod.so $L/tst-ptrguard-static-dlopen-mod.so From patchwork Wed Jun 3 00:04:33 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 136336 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1E8094BA2E15 for ; Wed, 3 Jun 2026 00:08:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1E8094BA2E15 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=qKTEJSyX X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-yw1-x112b.google.com (mail-yw1-x112b.google.com [IPv6:2607:f8b0:4864:20::112b]) by sourceware.org (Postfix) with ESMTPS id 8CB7D4BA23C6 for ; Wed, 3 Jun 2026 00:07:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8CB7D4BA23C6 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 8CB7D4BA23C6 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::112b ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445229; cv=none; b=FuPnuU1Z/MeUJs/JwWQk1dghlUzYqezdyFD6q4WV8jZbhddYRESmMypTBWQixvPfVgeJrxFPwUET6FREh4G76AcSUqtNaN5lVSAzFRWnik//W1nCLhmraT4JGBq0+a1iu5P/yujyrernxw3y75sRZ3vQ+Y3X3B9Oxl+l8B6y0Q8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445229; c=relaxed/simple; bh=4hBsu/MU7L4zgfWmyTbrCgZWk4mIUXgDdlo02DbCCCU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=H98/JtHIxKpbZjIf3HXt+5vvbkykNQfljc1YSn/pvaZupp7mqKYKlfD0otgfcVYFw7YoxPdpveolJNUYC8fcQuIG9+iXT26FM9WylUOdc+wrn03sQbg4mtj/BuDXMz33walQVNixWqqdSigrOL6z1OyBImQf6Fn6EFiSJS0HaeI= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=qKTEJSyX DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8CB7D4BA23C6 Received: by mail-yw1-x112b.google.com with SMTP id 00721157ae682-7e0aa486af8so768807b3.1 for ; Tue, 02 Jun 2026 17:07:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1780445228; x=1781050028; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sBFQbs/PvPOIBgJIzNbIzIXHOJi38UEzgbMyyyRj04g=; b=qKTEJSyXJfXeqwzN/JLcG4gfckzm3O6sCfInkib+FQQrXtashBk1iMjgMd7MnNUaWg jg50x7ROW87T03uXTgNCjyKwNwlYVhS2czOB2hhdcqlawJE3CczW4tnygDxdPGnMA2S+ eEQLkvuDpjKJrt4E+kspzxFTw9kMOoo62L6Ry8BWh1+OXQY0H1xYWZYiT5Va82ORYBUG CbJqLVpIlEEA168+dohFXS1Lo7Xnksoe9DaoaQaYvlpivNKK7S3tsjFFzBTQpTZq0Us8 agJ8nlxBzwvYTCZT1VbQrh78jFJtVIEsXP1NXD6TayxIDPvE01x8kpBsMdH52cbD5hrd Lf7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780445228; x=1781050028; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=sBFQbs/PvPOIBgJIzNbIzIXHOJi38UEzgbMyyyRj04g=; b=drtGwql9JfrrZn5RxwYCDTV2CHUp3TpSNViXUHvrvR0SeglsPDs0TllKAi1vGvVoPZ hiFtphuTogi4LMUM4e6siSrFVmj2BTc0Ls5DLqKWNS/fhDDt/Cmdib1sMXOGU1cpsuh4 3abACtJ6oG2BAZmaZtBFWUnSD/sq53HJkBw6do8RYSguKMdXP0Vb7zwH0qv6UYj8D0eY zAsQ6MV+0d7oZPIpQBaR/UO6P41w+REtCP4pUMDU4NojSBQ4DU5D6IwOTgE0R7wI36Uj y+7BOvfBnG5w3rnMUYumw9RrIbr81WOb084YNLZ3Ue0H7c2T8CzrbziaOHd7FzEhGtH4 2FkQ== X-Gm-Message-State: AOJu0Yz9hqCAb9oZVZjRAW8xRe0GJj0TUN2Ob4Ljdm2Co4k4JEYcpCTh 45gBAVFbjeVdxUSEM2PcUJ0pjejwrCKsG7FCmMKoHQ/zj6bTRN76nuzUxU0L/HnKd/KENFkkoIp UTcyh X-Gm-Gg: Acq92OEBZ4L/kXd384qSlZdiosqYEzJc/1NpNND33CqZtXcDUTxGovadg9BPiM/pJdq wJ99e7Y3Bbei9vArAWNaXMYNvvSIBQVA2PQcAJtDSjN0dPTylquFfOuwUa/tHzDF79NaISklXuB AfXI6LiDU5m/e5llRLEEDSr8cLEtpC38LX3RpjMqDdZ+yGo1t3oMVISv2X6aCttCucvzC572dWw TyXyt+CcAr5eFqV85H+c+ic5hHngCC3Q3Xj/AN8rWR4ec9xTP1W5Nuvux9/0tUhwB92IxsoO1mG JOs8xsQ0enX4LYyPENZy0YWRZFGEv5uJ6uXgYm0qOAn45t+2EIRygzXI9Okjk8GWSBfCc07nfmS ThPR98miMniffRowq13UdKMtPBSzpjkgBTuJ73Lgz3wjTSPbbQUcaEftUP+aW2XrZ0NWbBO3d9c LZZdT1dr/YEo0UrKFcT3rP6lwHhHo/AL6/NUY/4XTIWRC8Omw29CyhLdkb X-Received: by 2002:a05:690c:6b11:b0:7db:d576:483d with SMTP id 00721157ae682-7ea56ee13c5mr9036337b3.11.1780445227479; Tue, 02 Jun 2026 17:07:07 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:efc6:8f41:550d:2b14:9278]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7ea23a9946bsm7332207b3.37.2026.06.02.17.07.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jun 2026 17:07:06 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Anderson Nascimento , Carlos O'Donell Subject: [PATCH 2/8] Consolidate pointer guard to use a relro variable instead of the TCB Date: Tue, 2 Jun 2026 21:04:33 -0300 Message-ID: <20260603000656.3287796-3-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> References: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org For the targets that still read the pointer guard from the thread descriptor (i386, x86_64, powerpc, s390, sparc, and sh), mangle and demangle pointers using the module-local __pointer_chk_guard_local (in ld.so and static binaries) or the global __pointer_chk_guard provided by the dynamic loader (in shared objects), matching the scheme already used by aarch64, alpha, arm, csky and loongarch. This removes the dependency on the TCB pointer_guard slot: drop THREAD_{GET,SET,COPY}_POINTER_GUARD and the POINTER_GUARD tcb-offset, and point the POINTER_CHK_GUARD test macro at the relro variable. The tcbhead_t slot is kept (renamed to an unused reserved field, except on s390 which reused the stack guard) to preserve the ABI. s390 gains a distinct pointer guard rather than aliasing the stack guard. Checked on x86_64-linux-gnu, aarch64-linux-gnu, i686-linux-gnu, and armv7a-linux-gnueabihf. I also run elf and setjmp checks on qemu loongarch64, powerpc64, powerpc64le, and s390x systems. --- sysdeps/i386/htl/tcb-offsets.sym | 1 - sysdeps/i386/nptl/tcb-offsets.sym | 1 - sysdeps/i386/nptl/tls.h | 10 +--- sysdeps/i386/stackguard-macros.h | 10 +++- sysdeps/mach/hurd/i386/tls.h | 9 +-- sysdeps/mach/hurd/x86_64/tls.h | 8 +-- sysdeps/powerpc/nptl/tcb-offsets.sym | 1 - sysdeps/powerpc/nptl/tls.h | 16 +----- sysdeps/powerpc/powerpc32/stackguard-macros.h | 16 +++--- sysdeps/powerpc/powerpc64/stackguard-macros.h | 16 +++--- sysdeps/s390/__longjmp.c | 2 +- sysdeps/s390/nptl/tls.h | 7 --- sysdeps/s390/stackguard-macros.h | 20 +++---- sysdeps/sh/nptl/tcb-offsets.sym | 1 - sysdeps/sh/nptl/tls.h | 15 +---- sysdeps/sh/stackguard-macros.h | 8 ++- sysdeps/sparc/nptl/tcb-offsets.sym | 1 - sysdeps/sparc/nptl/tls.h | 10 +--- sysdeps/sparc/sparc32/stackguard-macros.h | 9 ++- sysdeps/sparc/sparc64/stackguard-macros.h | 9 ++- sysdeps/unix/sysv/linux/i386/pointer_guard.h | 50 +++++++++++++---- .../unix/sysv/linux/powerpc/pointer_guard.h | 55 ++++++++++++++----- sysdeps/unix/sysv/linux/s390/pointer_guard.h | 33 +++++++---- sysdeps/unix/sysv/linux/sh/pointer_guard.h | 53 +++++++++++++++--- .../sysv/linux/sparc/sparc32/pointer_guard.h | 40 ++++++++++++-- .../sysv/linux/sparc/sparc64/pointer_guard.h | 38 +++++++++++-- .../unix/sysv/linux/x86_64/pointer_guard.h | 18 +++--- sysdeps/x86_64/htl/tcb-offsets.sym | 1 - sysdeps/x86_64/nptl/tcb-offsets.sym | 1 - sysdeps/x86_64/nptl/tls.h | 10 +--- sysdeps/x86_64/stackguard-macros.h | 10 +++- 31 files changed, 290 insertions(+), 189 deletions(-) diff --git a/sysdeps/i386/htl/tcb-offsets.sym b/sysdeps/i386/htl/tcb-offsets.sym index 7b7c7193695..b36cfd6848a 100644 --- a/sysdeps/i386/htl/tcb-offsets.sym +++ b/sysdeps/i386/htl/tcb-offsets.sym @@ -4,5 +4,4 @@ MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) SIGSTATE_OFFSET offsetof (tcbhead_t, _hurd_sigstate) diff --git a/sysdeps/i386/nptl/tcb-offsets.sym b/sysdeps/i386/nptl/tcb-offsets.sym index 2ec9e787c1f..48f79845129 100644 --- a/sysdeps/i386/nptl/tcb-offsets.sym +++ b/sysdeps/i386/nptl/tcb-offsets.sym @@ -11,6 +11,5 @@ SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo) CLEANUP offsetof (struct pthread, cleanup) CLEANUP_PREV offsetof (struct _pthread_cleanup_buffer, __prev) MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) FEATURE_1_OFFSET offsetof (tcbhead_t, feature_1) SSP_BASE_OFFSET offsetof (tcbhead_t, ssp_base) diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h index 87dcf5dc1f4..fb8684230fb 100644 --- a/sysdeps/i386/nptl/tls.h +++ b/sysdeps/i386/nptl/tls.h @@ -39,7 +39,7 @@ typedef struct int multiple_threads; uintptr_t sysinfo; uintptr_t stack_guard; - uintptr_t pointer_guard; + uintptr_t __unused; int gscope_flag; /* Bit 0: X86_FEATURE_1_IBT. Bit 1: X86_FEATURE_1_SHSTK. @@ -240,14 +240,6 @@ tls_fill_user_desc (union user_desc_init *desc, = THREAD_GETMEM (THREAD_SELF, header.stack_guard)) -/* Set the pointer guard field in the TCB head. */ -#define THREAD_SET_POINTER_GUARD(value) \ - THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value) -#define THREAD_COPY_POINTER_GUARD(descr) \ - ((descr)->header.pointer_guard \ - = THREAD_GETMEM (THREAD_SELF, header.pointer_guard)) - - /* Get and set the global scope generation counter in the TCB head. */ #define THREAD_GSCOPE_FLAG_UNUSED 0 #define THREAD_GSCOPE_FLAG_USED 1 diff --git a/sysdeps/i386/stackguard-macros.h b/sysdeps/i386/stackguard-macros.h index 2939934ef19..696a9777027 100644 --- a/sysdeps/i386/stackguard-macros.h +++ b/sysdeps/i386/stackguard-macros.h @@ -1,3 +1,11 @@ +#include + #define STACK_CHK_GUARD (((tcbhead_t __seg_gs *)0)->stack_guard) -#define POINTER_CHK_GUARD (((tcbhead_t __seg_gs *)0)->pointer_guard) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h index 8cd643cdcf0..403395db9a8 100644 --- a/sysdeps/mach/hurd/i386/tls.h +++ b/sysdeps/mach/hurd/i386/tls.h @@ -36,7 +36,7 @@ typedef struct int multiple_threads; uintptr_t sysinfo; uintptr_t stack_guard; - uintptr_t pointer_guard; + uintptr_t __unused; int gscope_flag; unsigned int feature_1; /* Reservation of some values for the TM ABI. */ @@ -238,13 +238,6 @@ out: ((descr)->stack_guard \ = THREAD_GETMEM (THREAD_SELF, stack_guard)) -/* Set the pointer guard field in the TCB head. */ -#define THREAD_SET_POINTER_GUARD(value) \ - THREAD_SETMEM (THREAD_SELF, pointer_guard, value) -#define THREAD_COPY_POINTER_GUARD(descr) \ - ((descr)->pointer_guard \ - = THREAD_GETMEM (THREAD_SELF, pointer_guard)) - # include diff --git a/sysdeps/mach/hurd/x86_64/tls.h b/sysdeps/mach/hurd/x86_64/tls.h index 85ea75b5b51..3543e9be347 100644 --- a/sysdeps/mach/hurd/x86_64/tls.h +++ b/sysdeps/mach/hurd/x86_64/tls.h @@ -41,7 +41,7 @@ typedef struct int gscope_flag; uintptr_t sysinfo; uintptr_t stack_guard; - uintptr_t pointer_guard; + uintptr_t __unused; long __glibc_padding2[2]; int private_futex; int __glibc_padding3; @@ -125,12 +125,6 @@ THREAD_TCB (thread_t thread, ((descr)->stack_guard \ = THREAD_GETMEM (THREAD_SELF, stack_guard)) -/* Set the pointer guard field in the TCB head. */ -# define THREAD_SET_POINTER_GUARD(value) \ - THREAD_SETMEM (THREAD_SELF, pointer_guard, value) -# define THREAD_COPY_POINTER_GUARD(descr) \ - ((descr)->pointer_guard \ - = THREAD_GETMEM (THREAD_SELF, pointer_guard)) /* From hurd.h, reproduced here to avoid a circular include. */ extern thread_t __hurd_thread_self (void); diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym index 9b29fe8d1a1..bc88ecdddbf 100644 --- a/sysdeps/powerpc/nptl/tcb-offsets.sym +++ b/sysdeps/powerpc/nptl/tcb-offsets.sym @@ -14,7 +14,6 @@ MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) #endif TID thread_offsetof (tid) -POINTER_GUARD (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) TAR_SAVE (offsetof (tcbhead_t, tar_save) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) DSO_SLOT1 (offsetof (tcbhead_t, dso_slot1) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) DSO_SLOT2 (offsetof (tcbhead_t, dso_slot2) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h index 4ef6dd1a2fc..2e735c155bc 100644 --- a/sysdeps/powerpc/nptl/tls.h +++ b/sysdeps/powerpc/nptl/tls.h @@ -60,8 +60,7 @@ /* The stack_guard is accessed directly by GCC -fstack-protector code, - so it is a part of public ABI. The dtv and pointer_guard fields - are private. */ + so it is a part of public ABI. The dtv field is private. */ typedef struct { /* Reservation for HWCAP3 and HWCAP4 data. To be accessed by GCC in @@ -96,7 +95,7 @@ typedef struct uintptr_t ebb_ctx_pointer; uintptr_t ebb_reserved1; uintptr_t ebb_reserved2; - uintptr_t pointer_guard; + uintptr_t __unused2; uintptr_t stack_guard; dtv_t *dtv; } tcbhead_t; @@ -186,17 +185,6 @@ extern tcbhead_t __tcb attribute_hidden; = ((tcbhead_t *) ((char *) __thread_register \ - TLS_TCB_OFFSET))[-1].stack_guard) -/* Set the stack guard field in TCB head. */ -# define THREAD_GET_POINTER_GUARD() \ - (((tcbhead_t *) ((char *) __thread_register \ - - TLS_TCB_OFFSET))[-1].pointer_guard) -# define THREAD_SET_POINTER_GUARD(value) \ - (THREAD_GET_POINTER_GUARD () = (value)) -# define THREAD_COPY_POINTER_GUARD(descr) \ - (((tcbhead_t *) ((char *) (descr) \ - + TLS_PRE_TCB_SIZE))[-1].pointer_guard \ - = THREAD_GET_POINTER_GUARD()) - /* hwcap & hwcap_extn fields in TCB head. */ # define THREAD_GET_HWCAP() \ (((tcbhead_t *) ((char *) __thread_register \ diff --git a/sysdeps/powerpc/powerpc32/stackguard-macros.h b/sysdeps/powerpc/powerpc32/stackguard-macros.h index b3d0af830f2..0c94269a731 100644 --- a/sysdeps/powerpc/powerpc32/stackguard-macros.h +++ b/sysdeps/powerpc/powerpc32/stackguard-macros.h @@ -3,12 +3,10 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; asm ("lwz %0,-28680(2)" : "=r" (x)); x; }) -#define POINTER_CHK_GUARD \ - ({ \ - uintptr_t x; \ - asm ("lwz %0,%1(2)" \ - : "=r" (x) \ - : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) \ - ); \ - x; \ - }) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/powerpc/powerpc64/stackguard-macros.h b/sysdeps/powerpc/powerpc64/stackguard-macros.h index e80a683e64d..fec2e69f64c 100644 --- a/sysdeps/powerpc/powerpc64/stackguard-macros.h +++ b/sysdeps/powerpc/powerpc64/stackguard-macros.h @@ -3,12 +3,10 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; asm ("ld %0,-28688(13)" : "=r" (x)); x; }) -#define POINTER_CHK_GUARD \ - ({ \ - uintptr_t x; \ - asm ("ld %0,%1(13)" \ - : "=r" (x) \ - : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) \ - ); \ - x; \ - }) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/s390/__longjmp.c b/sysdeps/s390/__longjmp.c index 7c207e44c6d..78aa70a943c 100644 --- a/sysdeps/s390/__longjmp.c +++ b/sysdeps/s390/__longjmp.c @@ -35,7 +35,7 @@ void __longjmp (__jmp_buf env, int val) { #ifdef PTR_DEMANGLE - uintptr_t guard = THREAD_GET_POINTER_GUARD (); + uintptr_t guard = PTR_GUARD_VALUE; # ifdef CHECK_SP CHECK_SP (env, guard); # endif diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h index de7e9c64828..41fd473d14a 100644 --- a/sysdeps/s390/nptl/tls.h +++ b/sysdeps/s390/nptl/tls.h @@ -139,13 +139,6 @@ typedef struct ((descr)->header.stack_guard \ = THREAD_GETMEM (THREAD_SELF, header.stack_guard)) -/* s390 doesn't have HP_TIMING_*, so for the time being - use stack_guard as pointer_guard. */ -#define THREAD_GET_POINTER_GUARD() \ - THREAD_GETMEM (THREAD_SELF, header.stack_guard) -#define THREAD_SET_POINTER_GUARD(value) ((void) (value)) -#define THREAD_COPY_POINTER_GUARD(descr) - /* Get and set the global scope generation counter in struct pthread. */ #define THREAD_GSCOPE_FLAG_UNUSED 0 #define THREAD_GSCOPE_FLAG_USED 1 diff --git a/sysdeps/s390/stackguard-macros.h b/sysdeps/s390/stackguard-macros.h index 3671c7cd7a1..22e4751a73a 100644 --- a/sysdeps/s390/stackguard-macros.h +++ b/sysdeps/s390/stackguard-macros.h @@ -3,16 +3,10 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; __asm__ ("ear %0,%%a0; sllg %0,%0,32; ear %0,%%a1; lg %0,0x28(%0)" : "=a" (x)); x; }) -/* On s390x there is no unique pointer guard, instead we use the - same value as the stack guard. */ -#define POINTER_CHK_GUARD \ - ({ \ - uintptr_t x; \ - __asm__ ("ear %0,%%a0;" \ - "sllg %0,%0,32;" \ - "ear %0,%%a1;" \ - "lg %0,%1(%0)" \ - : "=a" (x) \ - : "i" (offsetof (tcbhead_t, stack_guard))); \ - x; \ - }) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/sh/nptl/tcb-offsets.sym b/sysdeps/sh/nptl/tcb-offsets.sym index 234207779dc..f1da9a05156 100644 --- a/sysdeps/sh/nptl/tcb-offsets.sym +++ b/sysdeps/sh/nptl/tcb-offsets.sym @@ -9,4 +9,3 @@ CLEANUP_JMP_BUF offsetof (struct pthread, cleanup_jmp_buf) MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) TLS_PRE_TCB_SIZE sizeof (struct pthread) MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h index eac95e14c75..7008003344c 100644 --- a/sysdeps/sh/nptl/tls.h +++ b/sysdeps/sh/nptl/tls.h @@ -33,7 +33,7 @@ typedef struct { dtv_t *dtv; - uintptr_t pointer_guard; + uintptr_t __unused; } tcbhead_t; # define TLS_MULTIPLE_THREADS_IN_TCB 1 @@ -109,19 +109,6 @@ typedef struct # include -#define THREAD_GET_POINTER_GUARD() \ - ({ tcbhead_t *__tcbp; \ - __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \ - __tcbp->pointer_guard;}) - #define THREAD_SET_POINTER_GUARD(value) \ - ({ tcbhead_t *__tcbp; \ - __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \ - __tcbp->pointer_guard = (value);}) -#define THREAD_COPY_POINTER_GUARD(descr) \ - ({ tcbhead_t *__tcbp; \ - __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \ - ((tcbhead_t *) (descr + 1))->pointer_guard = __tcbp->pointer_guard;}) - /* Get and set the global scope generation counter in struct pthread. */ #define THREAD_GSCOPE_FLAG_UNUSED 0 #define THREAD_GSCOPE_FLAG_USED 1 diff --git a/sysdeps/sh/stackguard-macros.h b/sysdeps/sh/stackguard-macros.h index 55a5771b629..b4a6b23ff87 100644 --- a/sysdeps/sh/stackguard-macros.h +++ b/sysdeps/sh/stackguard-macros.h @@ -3,4 +3,10 @@ extern uintptr_t __stack_chk_guard; #define STACK_CHK_GUARD __stack_chk_guard -#define POINTER_CHK_GUARD THREAD_GET_POINTER_GUARD() +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/sparc/nptl/tcb-offsets.sym b/sysdeps/sparc/nptl/tcb-offsets.sym index f75d02065ed..a64180da039 100644 --- a/sysdeps/sparc/nptl/tcb-offsets.sym +++ b/sysdeps/sparc/nptl/tcb-offsets.sym @@ -2,5 +2,4 @@ #include MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) TID offsetof (struct pthread, tid) diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h index cd2112a6500..361fc11a435 100644 --- a/sysdeps/sparc/nptl/tls.h +++ b/sysdeps/sparc/nptl/tls.h @@ -41,7 +41,7 @@ typedef struct #endif uintptr_t sysinfo; uintptr_t stack_guard; - uintptr_t pointer_guard; + uintptr_t __unused; #if __WORDSIZE != 64 int gscope_flag; #endif @@ -115,14 +115,6 @@ register struct pthread *__thread_self __asm__("%g7"); ((descr)->header.stack_guard \ = THREAD_GETMEM (THREAD_SELF, header.stack_guard)) -/* Get/set the stack guard field in TCB head. */ -#define THREAD_GET_POINTER_GUARD() \ - THREAD_GETMEM (THREAD_SELF, header.pointer_guard) -#define THREAD_SET_POINTER_GUARD(value) \ - THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value) -# define THREAD_COPY_POINTER_GUARD(descr) \ - ((descr)->header.pointer_guard = THREAD_GET_POINTER_GUARD ()) - /* Get and set the global scope generation counter in struct pthread. */ #define THREAD_GSCOPE_FLAG_UNUSED 0 #define THREAD_GSCOPE_FLAG_USED 1 diff --git a/sysdeps/sparc/sparc32/stackguard-macros.h b/sysdeps/sparc/sparc32/stackguard-macros.h index 1eef0f19f00..e8000a28991 100644 --- a/sysdeps/sparc/sparc32/stackguard-macros.h +++ b/sysdeps/sparc/sparc32/stackguard-macros.h @@ -3,5 +3,10 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; asm ("ld [%%g7+0x14], %0" : "=r" (x)); x; }) -#define POINTER_CHK_GUARD \ - ({ uintptr_t x; asm ("ld [%%g7+0x18], %0" : "=r" (x)); x; }) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/sparc/sparc64/stackguard-macros.h b/sysdeps/sparc/sparc64/stackguard-macros.h index cc0c12c0412..99978d8beca 100644 --- a/sysdeps/sparc/sparc64/stackguard-macros.h +++ b/sysdeps/sparc/sparc64/stackguard-macros.h @@ -3,5 +3,10 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; asm ("ldx [%%g7+0x28], %0" : "=r" (x)); x; }) -#define POINTER_CHK_GUARD \ - ({ uintptr_t x; asm ("ldx [%%g7+0x30], %0" : "=r" (x)); x; }) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard.h b/sysdeps/unix/sysv/linux/i386/pointer_guard.h index c8311be444b..d91b2342055 100644 --- a/sysdeps/unix/sysv/linux/i386/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/i386/pointer_guard.h @@ -19,26 +19,53 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#include - #if IS_IN (rtld) /* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. Using a global variable - is too complicated here since we have no PC-relative addressing mode. */ + earlier than the descriptor is initialized. */ # include #else # ifdef __ASSEMBLER__ -# define PTR_MANGLE(reg) xorl %gs:POINTER_GUARD, reg; \ +# include +# ifdef SHARED +/* The global guard is reached through the GOT. setjmp/__longjmp save and + restore %ebx and %esi around the mangling, so they can be used here as + the GOT pointer and a scratch register. */ +# define PTR_MANGLE(reg) LOAD_PIC_REG (bx); \ + movl __pointer_chk_guard@GOT(%ebx), %esi; \ + xorl (%esi), reg; \ roll $9, reg -# define PTR_DEMANGLE(reg) rorl $9, reg; \ - xorl %gs:POINTER_GUARD, reg +# define PTR_DEMANGLE(reg) rorl $9, reg; \ + LOAD_PIC_REG (bx); \ + movl __pointer_chk_guard@GOT(%ebx), %esi; \ + xorl (%esi), reg +# elif defined PIC +/* Static PIE: the module-local guard is reached via @GOTOFF. */ +# define PTR_MANGLE(reg) LOAD_PIC_REG (bx); \ + xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg; \ + roll $9, reg +# define PTR_DEMANGLE(reg) rorl $9, reg; \ + LOAD_PIC_REG (bx); \ + xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg +# else +/* Position-dependent code addresses the guard directly. */ +# define PTR_MANGLE(reg) xorl __pointer_chk_guard_local, reg; \ + roll $9, reg +# define PTR_DEMANGLE(reg) rorl $9, reg; \ + xorl __pointer_chk_guard_local, reg +# endif # else # include -# include +# include +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_GUARD_VALUE __pointer_chk_guard +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_GUARD_VALUE __pointer_chk_guard_local +# endif # define PTR_MANGLE(var) \ do { \ - (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ ((tcbhead_t __seg_gs *)0)->pointer_guard); \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ } while (0) @@ -46,8 +73,7 @@ do { \ (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ - (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ ((tcbhead_t __seg_gs *)0)->pointer_guard); \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ } while (0) # endif #endif diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h index 50d177224ff..864a78ea531 100644 --- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h @@ -20,34 +20,59 @@ #define POINTER_GUARD_H #if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ # include #else # ifdef __ASSEMBLER__ -# if defined(__PPC64__) || defined(__powerpc64__) -# define LOAD ld -# define TPREG r13 +# include +# ifdef SHARED +# define PTR_GUARD_SYM __pointer_chk_guard # else -# define LOAD lwz -# define TPREG r2 +# define PTR_GUARD_SYM __pointer_chk_guard_local # endif + +# if defined(__PPC64__) || defined(__powerpc64__) +# define PTR_GUARD_LOAD(tmpreg) \ + addis tmpreg,r2,PTR_GUARD_SYM@got@ha; \ + ld tmpreg,PTR_GUARD_SYM@got@l(tmpreg); \ + ld tmpreg,0(tmpreg) +# elif defined PIC +# define PTR_GUARD_LOAD(tmpreg) \ + mflr r12; \ + bcl 20,31,0f; \ +0: mflr tmpreg; \ + addis tmpreg,tmpreg,_GLOBAL_OFFSET_TABLE_-0b@ha; \ + addi tmpreg,tmpreg,_GLOBAL_OFFSET_TABLE_-0b@l; \ + mtlr r12; \ + lwz tmpreg,PTR_GUARD_SYM@got(tmpreg); \ + lwz tmpreg,0(tmpreg) +# else +# define PTR_GUARD_LOAD(tmpreg) \ + lis tmpreg,PTR_GUARD_SYM@ha; \ + lwz tmpreg,PTR_GUARD_SYM@l(tmpreg) +# endif + # define PTR_MANGLE(reg, tmpreg) \ - LOAD tmpreg,POINTER_GUARD(TPREG); \ - xor reg,tmpreg,reg + PTR_GUARD_LOAD (tmpreg); \ + xor reg,tmpreg,reg # define PTR_MANGLE2(reg, tmpreg) \ - xor reg,tmpreg,reg + xor reg,tmpreg,reg # define PTR_MANGLE3(destreg, reg, tmpreg) \ - LOAD tmpreg,POINTER_GUARD(TPREG); \ - xor destreg,tmpreg,reg + PTR_GUARD_LOAD (tmpreg); \ + xor destreg,tmpreg,reg # define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) # define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) # define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg) # else # include -# include -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# endif # define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif #endif diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard.h b/sysdeps/unix/sysv/linux/s390/pointer_guard.h index d7a574e94c6..aa75b8c42e5 100644 --- a/sysdeps/unix/sysv/linux/s390/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/s390/pointer_guard.h @@ -20,26 +20,37 @@ #define POINTER_GUARD_H #if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ # include #else -/* For the time being just use stack_guard rather than a separate - pointer_guard. */ # ifdef __ASSEMBLER__ +# ifdef SHARED +# define PTR_GUARD_LOAD(tmpreg) \ + larl tmpreg,__pointer_chk_guard@GOTENT; \ + lg tmpreg,0(tmpreg); \ + lg tmpreg,0(tmpreg) +# else +# define PTR_GUARD_LOAD(tmpreg) \ + larl tmpreg,__pointer_chk_guard_local; \ + lg tmpreg,0(tmpreg) +# endif # define PTR_MANGLE(reg, tmpreg) \ - ear tmpreg,%a0; \ - sllg tmpreg,tmpreg,32; \ - ear tmpreg,%a1; \ - xg reg,STACK_GUARD(tmpreg) + PTR_GUARD_LOAD (tmpreg); \ + xgr reg,tmpreg # define PTR_MANGLE2(reg, tmpreg) \ - xg reg,STACK_GUARD(tmpreg) + xgr reg,tmpreg # define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) +# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) # else # include -# include +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_GUARD_VALUE __pointer_chk_guard +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_GUARD_VALUE __pointer_chk_guard_local +# endif # define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) + (var) = (void *) ((uintptr_t) (var) ^ PTR_GUARD_VALUE) # define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif #endif diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard.h b/sysdeps/unix/sysv/linux/sh/pointer_guard.h index f1ec4b41f4f..fa989573c9e 100644 --- a/sysdeps/unix/sysv/linux/sh/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sh/pointer_guard.h @@ -1,4 +1,4 @@ -/* Pointer obfuscation implenentation. Generic (no-op) version. +/* Pointer obfuscation implenentation. SH version. Copyright (C) 2005-2026 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -20,22 +20,59 @@ #define POINTER_GUARD_H #if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. Using a global variable - is too complicated here since we have no PC-relative addressing mode. */ # include #else # ifdef __ASSEMBLER__ +# ifdef SHARED +# define PTR_GUARD_SYM __pointer_chk_guard +# else +# define PTR_GUARD_SYM __pointer_chk_guard_local +# endif +# ifdef PIC +# define PTR_GUARD_LOAD(tmp) \ + mov r0, r3; \ + mova .Lptrg_got, r0; \ + mov.l .Lptrg_got, tmp; \ + add r0, tmp; \ + mov.l .Lptrg_sym, r0; \ + mov.l @(r0, tmp), tmp; \ + mov r3, r0; \ + mov.l @tmp, tmp; \ + bra .Lptrg_end; \ + nop; \ + .align 2; \ +.Lptrg_got: \ + .long _GLOBAL_OFFSET_TABLE_; \ +.Lptrg_sym: \ + .long PTR_GUARD_SYM@GOT; \ +.Lptrg_end: +# else +# define PTR_GUARD_LOAD(tmp) \ + mov.l .Lptrg_sym, tmp; \ + mov.l @tmp, tmp; \ + bra .Lptrg_end; \ + nop; \ + .align 2; \ +.Lptrg_sym: \ + .long PTR_GUARD_SYM; \ +.Lptrg_end: +# endif # define PTR_MANGLE(reg, tmp) \ - stc gbr,tmp; mov.l @(POINTER_GUARD,tmp),tmp; xor tmp,reg + PTR_GUARD_LOAD (tmp); xor tmp,reg # define PTR_MANGLE2(reg, tmp) xor tmp,reg # define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp) # define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp) # else # include -# include -# define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard) +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# endif # define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif #endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h index 4359bf9fca6..43531defe99 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h @@ -25,18 +25,46 @@ # include #else # ifdef __ASSEMBLER__ +# include +# ifdef SHARED +# define PTR_GUARD_SYM __pointer_chk_guard +# else +# define PTR_GUARD_SYM __pointer_chk_guard_local +# endif +# ifdef PIC +/* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT + pointer in %o2 while preserving %o7 (the return address, which setjmp + mangles), using %o3 as a scratch register; both are dead at every + mangling site. */ +# define PTR_GUARD_LOAD(tmpreg) \ + SETUP_PIC_REG_LEAF(o2, o3); \ + sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ + xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ + ld [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ + ld [tmpreg], tmpreg +# else +# define PTR_GUARD_LOAD(tmpreg) \ + sethi %hi(PTR_GUARD_SYM), tmpreg; \ + ld [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg +# endif # define PTR_MANGLE(dreg, reg, tmpreg) \ - ld [%g7 + POINTER_GUARD], tmpreg; \ - xor reg, tmpreg, dreg + PTR_GUARD_LOAD (tmpreg); \ + xor reg, tmpreg, dreg # define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) # define PTR_MANGLE2(dreg, reg, tmpreg) \ - xor reg, tmpreg, dreg + xor reg, tmpreg, dreg # define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) # else # include -# include -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# endif # define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif #endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h index 91bc1f4d85e..6515e0dd072 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h @@ -25,18 +25,44 @@ # include #else # ifdef __ASSEMBLER__ +# include +# ifdef SHARED +# define PTR_GUARD_SYM __pointer_chk_guard +# else +# define PTR_GUARD_SYM __pointer_chk_guard_local +# endif +# ifdef PIC +/* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT + pointer in %o2 while preserving %o7, using %o3 as a scratch register. */ +# define PTR_GUARD_LOAD(tmpreg) \ + SETUP_PIC_REG_LEAF(o2, o3); \ + sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ + xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ + ldx [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ + ldx [tmpreg], tmpreg +# else +# define PTR_GUARD_LOAD(tmpreg) \ + sethi %hi(PTR_GUARD_SYM), tmpreg; \ + ldx [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg +# endif # define PTR_MANGLE(dreg, reg, tmpreg) \ - ldx [%g7 + POINTER_GUARD], tmpreg; \ - xor reg, tmpreg, dreg + PTR_GUARD_LOAD (tmpreg); \ + xor reg, tmpreg, dreg # define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) # define PTR_MANGLE2(dreg, reg, tmpreg) \ - xor reg, tmpreg, dreg + xor reg, tmpreg, dreg # define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) # else # include -# include -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# endif # define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif #endif diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h index 4f7abc64f49..6d09b429cd2 100644 --- a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h @@ -22,9 +22,8 @@ #include #include -#if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ +#if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) # ifdef __ASSEMBLER__ # define PTR_MANGLE(reg) xor __pointer_chk_guard_local(%rip), reg; \ rol $2*LP_SIZE+1, reg @@ -51,17 +50,20 @@ extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; # endif #else # ifdef __ASSEMBLER__ -# define PTR_MANGLE(reg) xor %fs:POINTER_GUARD, reg; \ +# define PTR_MANGLE(reg) mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP;\ + xor (%R11_LP), reg; \ rol $2*LP_SIZE+1, reg # define PTR_DEMANGLE(reg) ror $2*LP_SIZE+1, reg; \ - xor %fs:POINTER_GUARD, reg + mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP;\ + xor (%R11_LP), reg # else # include -# include +# include +extern uintptr_t __pointer_chk_guard attribute_relro; # define PTR_MANGLE(var) \ do { \ (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ ((tcbhead_t __seg_fs *)0)->pointer_guard); \ + ^ __pointer_chk_guard); \ (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ } while (0) @@ -70,7 +72,7 @@ extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ ((tcbhead_t __seg_fs *)0)->pointer_guard); \ + ^ __pointer_chk_guard); \ } while (0) # endif #endif diff --git a/sysdeps/x86_64/htl/tcb-offsets.sym b/sysdeps/x86_64/htl/tcb-offsets.sym index 7b7c7193695..b36cfd6848a 100644 --- a/sysdeps/x86_64/htl/tcb-offsets.sym +++ b/sysdeps/x86_64/htl/tcb-offsets.sym @@ -4,5 +4,4 @@ MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) SIGSTATE_OFFSET offsetof (tcbhead_t, _hurd_sigstate) diff --git a/sysdeps/x86_64/nptl/tcb-offsets.sym b/sysdeps/x86_64/nptl/tcb-offsets.sym index 988a4b85936..aaa1dacd0cc 100644 --- a/sysdeps/x86_64/nptl/tcb-offsets.sym +++ b/sysdeps/x86_64/nptl/tcb-offsets.sym @@ -10,6 +10,5 @@ CLEANUP offsetof (struct pthread, cleanup) CLEANUP_PREV offsetof (struct _pthread_cleanup_buffer, __prev) MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) FEATURE_1_OFFSET offsetof (tcbhead_t, feature_1) SSP_BASE_OFFSET offsetof (tcbhead_t, ssp_base) diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h index 836b2e22440..413ab074bf8 100644 --- a/sysdeps/x86_64/nptl/tls.h +++ b/sysdeps/x86_64/nptl/tls.h @@ -49,7 +49,7 @@ typedef struct int gscope_flag; uintptr_t sysinfo; uintptr_t stack_guard; - uintptr_t pointer_guard; + uintptr_t __unused; unsigned long int unused_vgetcpu_cache[2]; /* Bit 0: X86_FEATURE_1_IBT. Bit 1: X86_FEATURE_1_SHSTK. @@ -186,14 +186,6 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80, = THREAD_GETMEM (THREAD_SELF, header.stack_guard)) -/* Set the pointer guard field in the TCB head. */ -# define THREAD_SET_POINTER_GUARD(value) \ - THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value) -# define THREAD_COPY_POINTER_GUARD(descr) \ - ((descr)->header.pointer_guard \ - = THREAD_GETMEM (THREAD_SELF, header.pointer_guard)) - - /* Get and set the global scope generation counter in the TCB head. */ # define THREAD_GSCOPE_FLAG_UNUSED 0 # define THREAD_GSCOPE_FLAG_USED 1 diff --git a/sysdeps/x86_64/stackguard-macros.h b/sysdeps/x86_64/stackguard-macros.h index 77f13c986d8..3d685e0f828 100644 --- a/sysdeps/x86_64/stackguard-macros.h +++ b/sysdeps/x86_64/stackguard-macros.h @@ -1,3 +1,11 @@ +#include + #define STACK_CHK_GUARD (((tcbhead_t __seg_fs *)0)->stack_guard) -#define POINTER_CHK_GUARD (((tcbhead_t __seg_fs *)0)->pointer_guard) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif From patchwork Wed Jun 3 00:04:34 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 136334 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 420844BA2E37 for ; Wed, 3 Jun 2026 00:07:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 420844BA2E37 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=M+RtSlT5 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com [IPv6:2607:f8b0:4864:20::1132]) by sourceware.org (Postfix) with ESMTPS id 6770F4BA2E3C for ; Wed, 3 Jun 2026 00:07:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6770F4BA2E3C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6770F4BA2E3C Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1132 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445230; cv=none; b=M4Mnc8xtWYuOVtF4JLpoJjSStoGdjZQylfB3YrCx91RVzqoy6pHeCTLzMtz0xfR3Chz4pOdD/JmD+kWyMYV9c7BCnjrA3+PORsLzKbGRv6nusuTtRSC+Uy7oWlKNSQaipO5QnaRGZkF6XKCzea0efktYTjTl0Xc/wKsuVPVjgQM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445230; c=relaxed/simple; bh=9V6epScK1xsYBVIwqv7Sn5KXgLKaObsqLObuwYvbY4Q=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=NH9gBphLSLrAIz+RB2yh+ta46uTCheQkFWR4ZqXRefwZW8MlqxpgccnbLv9XJVWOknAIRHW32FElilZEeBOW82YmrqsupxsdnOhRfrs1rYTE30cnA/cTfTFaiRgGTGc3Ssn6Na1O0kysrF1PXvwlc5Z6VYma7IJ/p/We7P4kdCk= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=M+RtSlT5 DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6770F4BA2E3C Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-7dc93d02916so61418637b3.3 for ; Tue, 02 Jun 2026 17:07:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1780445230; x=1781050030; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1qS7POtD2+hnDKTkdvycPY54fNUWpUTbuhEp0IwOdzQ=; b=M+RtSlT51TeUoWGH2m1Gm4uRqR4RTHeIMtkbTkmJM8JuHDfZ/sCgiF7HMi63Vj4VCk KYS0jxoUyAHdJNT4t48qSQrKwrfA37MitSonJNd2BTne3uwIOvOMlLahZJgPjqYYgLAB Ck1ZvyLl9ZOWEH4rgmLof6ina2ft9al4QkyAIRdjmW+3HzGdaL4P9IfHNdsBR272kyeq P8ePKJKXBqQ+sXtAUPU++9bacylc51xlnNWtrMUNq22vb21XsmknfFbrBQ4O1cUB8i4g CsqPPRTmKLtbjYLoU2i1trpID8Uw4vq7HbPtEd/PpWMAewzvsA9CFy+yDabSFfCtx84F haWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780445230; x=1781050030; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=1qS7POtD2+hnDKTkdvycPY54fNUWpUTbuhEp0IwOdzQ=; b=H1KvEasPy3lGvE6X8h1sn1XUMG3l0tSKrOuiDDpR1nEFKzKdqYE16z5gurIpcZn7nt OVshPrl0hjM6MKAu7Xk8Tnk9kIJAOS1asVIMiEEfnQL2K8WOSSTAdzXBh+EOyMgJQxq3 ZaOnpJx3XdwXlLI6Y/Sc0anRMSQT24ujLPzoz9BEj7TBnTTOexglQLv0bbuOVtkBTHMv +d1GJmaMWIBgtcBi1kq+/9xVkkHyouyjpR2Z0u+bcEAMIztRZeaC1JyrpmW47vQJEVo3 GHR9GUviRfNDj6kGv5ZX6N1trui9yYYGfbuFdcS4FrZP8/DOlK0t1Tl2HKa7Xpl+TMUi 40hA== X-Gm-Message-State: AOJu0YwXCutawtylUjGCATnu/T0vaEOzq7QqfVU6E0k2qVJp3ssm16ij iFfYbQGk+U5iajfUu8Idffjh9HqlfAHJG//8kocteD8X4sNzNZFPyHADL0rp8kaHuoICgfMblwQ ps5wX X-Gm-Gg: Acq92OExKuJFWTJPdzGYJFIM6iReC/EhNLH+PRvGuAtIHCMcMYAJoDIVrlZYIVIEkYV 1Ew1ZfEN52I0dhWT/2PES56YsTYBf+PaZWk3cQ+l8Xgx+tIsSfBcG5flIWozvyQbZzPuTyaFcmv eO7f0KMDejcKOksoZqGJ+kQ4IagCFUAGeNcAT9xDZV+Aap9AY6G/d44SPlYsiAvvgZMIiOuuhSS sbSTfmMpaK2xKxkk3EPaeJRy2zcZ/1n699pHuhExk4s0CchQxpk26k6bG0sJ97OVROKDU/+s/ob kYyoGC6Z47lA+9xuYbJtj6eKWj579mCSS75OQd3kWBOy+r5vH3aVyeRa6Be8YHFF9vVkVG57EnL 1I03H0YiVDh5u/3crsztcuNTOyW4ILC9p0rF4GLkic5ShXMZGNb/FfVnI10VXPdbhP9N9kbUdRV WqDMgJxy7ELxtHHzynxMMClaZejyvNL31rSi/c93Ono3kLhg== X-Received: by 2002:a05:690c:310:b0:7b8:338d:7d80 with SMTP id 00721157ae682-7ea4bad9519mr10325447b3.31.1780445229554; Tue, 02 Jun 2026 17:07:09 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:efc6:8f41:550d:2b14:9278]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7ea23a9946bsm7332207b3.37.2026.06.02.17.07.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jun 2026 17:07:09 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Anderson Nascimento , Carlos O'Donell Subject: [PATCH 3/8] Enable the pointer guard in the dynamic loader Date: Tue, 2 Jun 2026 21:04:34 -0300 Message-ID: <20260603000656.3287796-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> References: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org i386, powerpc, s390, sh and sparc fell back to the generic no-op pointer_guard.h in ld.so, so the loader's own setjmp/longjmp and mangled function pointers were left unprotected (the other targets already mangle in rtld). ld.so is position-independent and sets up __pointer_chk_guard_local early in dl_main, so the loader can reach it the same way a statically linked program does: - powerpc, s390, sh, sparc: select __pointer_chk_guard_local for IS_IN (rtld) and reuse the existing PIC guard load. - i386: load it via @GOTOFF off a GOT pointer set up with LOAD_PIC_REG (ld.so does not keep the GOT in %ebx at the setjmp/longjmp entry). - s390: drop the IS_IN (rtld) "#undef PTR_DEMANGLE" in __longjmp.c so the loader's longjmp demangles to match its setjmp. Checked on x86_64-linux-gnu, aarch64-linux-gnu, i686-linux-gnu, and armv7a-linux-gnueabihf. I also run elf and setjmp checks on qemu loongarch64, powerpc64, powerpc64le, and s390x systems. --- sysdeps/s390/__longjmp.c | 5 -- sysdeps/unix/sysv/linux/i386/pointer_guard.h | 57 ++++++-------- .../unix/sysv/linux/powerpc/pointer_guard.h | 78 ++++++++++--------- sysdeps/unix/sysv/linux/s390/pointer_guard.h | 52 ++++++------- sysdeps/unix/sysv/linux/sh/pointer_guard.h | 65 ++++++++-------- .../sysv/linux/sparc/sparc32/pointer_guard.h | 59 +++++++------- .../sysv/linux/sparc/sparc64/pointer_guard.h | 59 +++++++------- 7 files changed, 183 insertions(+), 192 deletions(-) diff --git a/sysdeps/s390/__longjmp.c b/sysdeps/s390/__longjmp.c index 78aa70a943c..50d67bf42cc 100644 --- a/sysdeps/s390/__longjmp.c +++ b/sysdeps/s390/__longjmp.c @@ -24,11 +24,6 @@ #include #include -/* See sysdeps/unix/sysv/linux/s390/pointer_guard.h. */ -#if IS_IN (rtld) -# undef PTR_DEMANGLE -#endif - /* Jump to the position specified by ENV, causing the setjmp call there to return VAL, or 1 if VAL is 0. */ void diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard.h b/sysdeps/unix/sysv/linux/i386/pointer_guard.h index d91b2342055..63308d84e76 100644 --- a/sysdeps/unix/sysv/linux/i386/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/i386/pointer_guard.h @@ -19,27 +19,10 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ -# include -#else -# ifdef __ASSEMBLER__ -# include -# ifdef SHARED -/* The global guard is reached through the GOT. setjmp/__longjmp save and - restore %ebx and %esi around the mangling, so they can be used here as - the GOT pointer and a scratch register. */ -# define PTR_MANGLE(reg) LOAD_PIC_REG (bx); \ - movl __pointer_chk_guard@GOT(%ebx), %esi; \ - xorl (%esi), reg; \ - roll $9, reg -# define PTR_DEMANGLE(reg) rorl $9, reg; \ - LOAD_PIC_REG (bx); \ - movl __pointer_chk_guard@GOT(%ebx), %esi; \ - xorl (%esi), reg -# elif defined PIC -/* Static PIE: the module-local guard is reached via @GOTOFF. */ +#ifdef __ASSEMBLER__ +# include +# if IS_IN (rtld) || !defined SHARED +# ifdef PIC # define PTR_MANGLE(reg) LOAD_PIC_REG (bx); \ xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg; \ roll $9, reg @@ -47,35 +30,43 @@ LOAD_PIC_REG (bx); \ xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg # else -/* Position-dependent code addresses the guard directly. */ # define PTR_MANGLE(reg) xorl __pointer_chk_guard_local, reg; \ roll $9, reg # define PTR_DEMANGLE(reg) rorl $9, reg; \ xorl __pointer_chk_guard_local, reg # endif # else -# include -# include -# ifdef SHARED -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_GUARD_VALUE __pointer_chk_guard -# else +# define PTR_MANGLE(reg) LOAD_PIC_REG (bx); \ + movl __pointer_chk_guard@GOT(%ebx), %esi; \ + xorl (%esi), reg; \ + roll $9, reg +# define PTR_DEMANGLE(reg) rorl $9, reg; \ + LOAD_PIC_REG (bx); \ + movl __pointer_chk_guard@GOT(%ebx), %esi; \ + xorl (%esi), reg +# endif +#else +# include +# include +# if IS_IN (rtld) || !defined SHARED extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_GUARD_VALUE __pointer_chk_guard_local -# endif -# define PTR_MANGLE(var) \ +# define PTR_GUARD_VALUE __pointer_chk_guard_local +# else +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_GUARD_VALUE __pointer_chk_guard +# endif +# define PTR_MANGLE(var) \ do { \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ } while (0) -# define PTR_DEMANGLE(var) \ +# define PTR_DEMANGLE(var) \ do { \ (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ } while (0) -# endif #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h index 864a78ea531..271cf93c2f4 100644 --- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h @@ -1,4 +1,4 @@ -/* Pointer obfuscation implenentation. PowerpC version. +/* Pointer obfuscation implenentation. PowerPC version. Copyright (C) 2005-2026 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -19,24 +19,32 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -# include -#else -# ifdef __ASSEMBLER__ -# include -# ifdef SHARED -# define PTR_GUARD_SYM __pointer_chk_guard -# else -# define PTR_GUARD_SYM __pointer_chk_guard_local -# endif +/* In ld.so and in statically linked programs the guard is the module-local + relro variable __pointer_chk_guard_local; in other shared objects it is + the global __pointer_chk_guard provided by the dynamic loader. */ +#ifdef __ASSEMBLER__ +# include +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif -# if defined(__PPC64__) || defined(__powerpc64__) -# define PTR_GUARD_LOAD(tmpreg) \ +# if defined(__PPC64__) || defined(__powerpc64__) +/* r2 (the TOC pointer) is always available, so load the guard's address + from the TOC/GOT and dereference it. */ +# define PTR_GUARD_LOAD(tmpreg) \ addis tmpreg,r2,PTR_GUARD_SYM@got@ha; \ ld tmpreg,PTR_GUARD_SYM@got@l(tmpreg); \ ld tmpreg,0(tmpreg) -# elif defined PIC -# define PTR_GUARD_LOAD(tmpreg) \ +# elif defined PIC +/* Position-independent 32-bit code has no dedicated GOT register here, so + establish one with the usual bcl/mflr sequence. GAS numeric local labels + are used so the sequence can be expanded more than once per file. LR is + clobbered by the bcl, so it is saved in r12 (a volatile register that is + not otherwise live at the mangling points) and restored; r0 must not be + used here as it holds the saved link register in __longjmp. */ +# define PTR_GUARD_LOAD(tmpreg) \ mflr r12; \ bcl 20,31,0f; \ 0: mflr tmpreg; \ @@ -45,36 +53,36 @@ mtlr r12; \ lwz tmpreg,PTR_GUARD_SYM@got(tmpreg); \ lwz tmpreg,0(tmpreg) -# else -# define PTR_GUARD_LOAD(tmpreg) \ - lis tmpreg,PTR_GUARD_SYM@ha; \ +# else +/* Position-dependent 32-bit code can address the variable directly. */ +# define PTR_GUARD_LOAD(tmpreg) \ + lis tmpreg,PTR_GUARD_SYM@ha; \ lwz tmpreg,PTR_GUARD_SYM@l(tmpreg) -# endif +# endif -# define PTR_MANGLE(reg, tmpreg) \ +# define PTR_MANGLE(reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ xor reg,tmpreg,reg -# define PTR_MANGLE2(reg, tmpreg) \ +# define PTR_MANGLE2(reg, tmpreg) \ xor reg,tmpreg,reg -# define PTR_MANGLE3(destreg, reg, tmpreg) \ +# define PTR_MANGLE3(destreg, reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ xor destreg,tmpreg,reg -# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) -# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) -# define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg) -# else -# include -# ifdef SHARED -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -# else +# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) +# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) +# define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg) +#else +# include +# if IS_IN (rtld) || !defined SHARED extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ +# define PTR_MANGLE(var) \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# else +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) # endif +# define PTR_DEMANGLE(var) PTR_MANGLE (var) #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard.h b/sysdeps/unix/sysv/linux/s390/pointer_guard.h index aa75b8c42e5..a4ec92f6655 100644 --- a/sysdeps/unix/sysv/linux/s390/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/s390/pointer_guard.h @@ -19,40 +19,40 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -# include -#else -# ifdef __ASSEMBLER__ -# ifdef SHARED -# define PTR_GUARD_LOAD(tmpreg) \ +/* In ld.so and in statically linked programs the guard is the module-local + relro variable __pointer_chk_guard_local, reached PC-relatively with larl; + in other shared objects it is the global __pointer_chk_guard provided by + the dynamic loader, reached through the GOT. */ +#ifdef __ASSEMBLER__ +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_LOAD(tmpreg) \ + larl tmpreg,__pointer_chk_guard_local; \ + lg tmpreg,0(tmpreg) +# else +# define PTR_GUARD_LOAD(tmpreg) \ larl tmpreg,__pointer_chk_guard@GOTENT; \ lg tmpreg,0(tmpreg); \ lg tmpreg,0(tmpreg) -# else -# define PTR_GUARD_LOAD(tmpreg) \ - larl tmpreg,__pointer_chk_guard_local; \ - lg tmpreg,0(tmpreg) -# endif -# define PTR_MANGLE(reg, tmpreg) \ +# endif +# define PTR_MANGLE(reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ xgr reg,tmpreg -# define PTR_MANGLE2(reg, tmpreg) \ +# define PTR_MANGLE2(reg, tmpreg) \ xgr reg,tmpreg -# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) -# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) -# else -# include -# ifdef SHARED -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_GUARD_VALUE __pointer_chk_guard -# else +# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) +# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) +#else +# include +# if IS_IN (rtld) || !defined SHARED extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_GUARD_VALUE __pointer_chk_guard_local -# endif -# define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ PTR_GUARD_VALUE) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# define PTR_GUARD_VALUE __pointer_chk_guard_local +# else +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_GUARD_VALUE __pointer_chk_guard # endif +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ PTR_GUARD_VALUE) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard.h b/sysdeps/unix/sysv/linux/sh/pointer_guard.h index fa989573c9e..9a1e01a452c 100644 --- a/sysdeps/unix/sysv/linux/sh/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sh/pointer_guard.h @@ -19,17 +19,21 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -# include -#else -# ifdef __ASSEMBLER__ -# ifdef SHARED -# define PTR_GUARD_SYM __pointer_chk_guard -# else -# define PTR_GUARD_SYM __pointer_chk_guard_local -# endif -# ifdef PIC -# define PTR_GUARD_LOAD(tmp) \ +/* In ld.so and in statically linked programs the guard is the module-local + relro variable __pointer_chk_guard_local; in other shared objects it is + the global __pointer_chk_guard provided by the dynamic loader. */ +#ifdef __ASSEMBLER__ +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif +# ifdef PIC +/* Load the guard through the GOT. The GOT pointer is computed with the + usual mova/mov.l sequence which clobbers r0; in __longjmp r0 holds the + return value, so it is saved in r3 (dead at every mangling site) and + restored. A literal pool is emitted inline and branched over. */ +# define PTR_GUARD_LOAD(tmp) \ mov r0, r3; \ mova .Lptrg_got, r0; \ mov.l .Lptrg_got, tmp; \ @@ -46,8 +50,8 @@ .Lptrg_sym: \ .long PTR_GUARD_SYM@GOT; \ .Lptrg_end: -# else -# define PTR_GUARD_LOAD(tmp) \ +# else +# define PTR_GUARD_LOAD(tmp) \ mov.l .Lptrg_sym, tmp; \ mov.l @tmp, tmp; \ bra .Lptrg_end; \ @@ -56,25 +60,24 @@ .Lptrg_sym: \ .long PTR_GUARD_SYM; \ .Lptrg_end: -# endif -# define PTR_MANGLE(reg, tmp) \ - PTR_GUARD_LOAD (tmp); xor tmp,reg -# define PTR_MANGLE2(reg, tmp) xor tmp,reg -# define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp) -# define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp) -# else -# include -# ifdef SHARED -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard) -# else -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif +# define PTR_MANGLE(reg, tmp) \ + PTR_GUARD_LOAD (tmp); xor tmp,reg +# define PTR_MANGLE2(reg, tmp) xor tmp,reg +# define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp) +# define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp) +#else +# include +# if IS_IN (rtld) || !defined SHARED +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# else +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard) +# endif +# define PTR_DEMANGLE(var) PTR_MANGLE (var) #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h index 43531defe99..2242981f6bd 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h @@ -19,54 +19,51 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ -# include -#else -# ifdef __ASSEMBLER__ -# include -# ifdef SHARED -# define PTR_GUARD_SYM __pointer_chk_guard -# else -# define PTR_GUARD_SYM __pointer_chk_guard_local -# endif -# ifdef PIC +/* In ld.so and in statically linked programs the guard is the module-local + relro variable __pointer_chk_guard_local; in other shared objects it is + the global __pointer_chk_guard provided by the dynamic loader. */ +#ifdef __ASSEMBLER__ +# include +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif +# ifdef PIC /* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT pointer in %o2 while preserving %o7 (the return address, which setjmp mangles), using %o3 as a scratch register; both are dead at every mangling site. */ -# define PTR_GUARD_LOAD(tmpreg) \ +# define PTR_GUARD_LOAD(tmpreg) \ SETUP_PIC_REG_LEAF(o2, o3); \ sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ ld [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ ld [tmpreg], tmpreg -# else -# define PTR_GUARD_LOAD(tmpreg) \ +# else +# define PTR_GUARD_LOAD(tmpreg) \ sethi %hi(PTR_GUARD_SYM), tmpreg; \ ld [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg -# endif -# define PTR_MANGLE(dreg, reg, tmpreg) \ +# endif +# define PTR_MANGLE(dreg, reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ xor reg, tmpreg, dreg -# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) -# define PTR_MANGLE2(dreg, reg, tmpreg) \ +# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) +# define PTR_MANGLE2(dreg, reg, tmpreg) \ xor reg, tmpreg, dreg -# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) -# else -# include -# ifdef SHARED -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -# else +# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) +#else +# include +# if IS_IN (rtld) || !defined SHARED extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ +# define PTR_MANGLE(var) \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# else +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) # endif +# define PTR_DEMANGLE(var) PTR_MANGLE (var) #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h index 6515e0dd072..8cdb2edf7be 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h @@ -19,52 +19,49 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ -# include -#else -# ifdef __ASSEMBLER__ -# include -# ifdef SHARED -# define PTR_GUARD_SYM __pointer_chk_guard -# else -# define PTR_GUARD_SYM __pointer_chk_guard_local -# endif -# ifdef PIC +/* In ld.so and in statically linked programs the guard is the module-local + relro variable __pointer_chk_guard_local; in other shared objects it is + the global __pointer_chk_guard provided by the dynamic loader. */ +#ifdef __ASSEMBLER__ +# include +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif +# ifdef PIC /* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT pointer in %o2 while preserving %o7, using %o3 as a scratch register. */ -# define PTR_GUARD_LOAD(tmpreg) \ +# define PTR_GUARD_LOAD(tmpreg) \ SETUP_PIC_REG_LEAF(o2, o3); \ sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ ldx [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ ldx [tmpreg], tmpreg -# else -# define PTR_GUARD_LOAD(tmpreg) \ +# else +# define PTR_GUARD_LOAD(tmpreg) \ sethi %hi(PTR_GUARD_SYM), tmpreg; \ ldx [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg -# endif -# define PTR_MANGLE(dreg, reg, tmpreg) \ +# endif +# define PTR_MANGLE(dreg, reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ xor reg, tmpreg, dreg -# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) -# define PTR_MANGLE2(dreg, reg, tmpreg) \ +# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) +# define PTR_MANGLE2(dreg, reg, tmpreg) \ xor reg, tmpreg, dreg -# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) -# else -# include -# ifdef SHARED -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -# else +# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) +#else +# include +# if IS_IN (rtld) || !defined SHARED extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ +# define PTR_MANGLE(var) \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# else +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) # endif +# define PTR_DEMANGLE(var) PTR_MANGLE (var) #endif #endif /* POINTER_GUARD_H */ From patchwork Wed Jun 3 00:04:35 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 136338 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0A8DE4BA23C7 for ; Wed, 3 Jun 2026 00:10:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0A8DE4BA23C7 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=D6GJs07G X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-yw1-x1130.google.com (mail-yw1-x1130.google.com [IPv6:2607:f8b0:4864:20::1130]) by sourceware.org (Postfix) with ESMTPS id 130F34BA2E2C for ; Wed, 3 Jun 2026 00:07:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 130F34BA2E2C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 130F34BA2E2C Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1130 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445233; cv=none; b=aePm5mQZYRPgIDfwfD3NiAagUg32juS1bg/7n95v90UaChJiDU+SnTC17ZkA4k2XxyhWDI9cn8mLc2GGqZ+0f/SKaIiH2iP2mZFQOaOGsJXIy8wyO3sOymMxksWCXvFAQUBWF9BFzCQvPQD63yCu/lDLHL7KAue9x/jbNt0LkfI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445233; c=relaxed/simple; bh=TemUuO0lGTqavLTenF+0PAzmPio9SYXiHAk+XQeFXb0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=gVHrCyEV4NfhL1BiJ9U2nXnBTFXgD7Uhh67p9obhOU1RO2wAH/xFbcCWmM+3om/WZHI8KmdRJTjIUN0U1wOGUv0oM8+bl3EjQwFW2+B95+PKyBeIy908puSJrOt5Bd6XyxCRP5QQ+G/MR5F6NthdCruwosRl1Ilx/zHNKKTOPFk= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=D6GJs07G DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 130F34BA2E2C Received: by mail-yw1-x1130.google.com with SMTP id 00721157ae682-7e87602f26aso1427807b3.1 for ; Tue, 02 Jun 2026 17:07:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1780445232; x=1781050032; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CmfRFiD30HCApEbL2wz95w04O6XoePglVU+31DCstWY=; b=D6GJs07Gf0+pfkn7MbeYmjAm71ylg7k9/XBDGRZ5wMFUmm6hXACZ59lvG26rh2L3Nn PV7L9a4SUZvmiiI60+3GuuRiOO4cbu4rq2pTsqX+6JcGUyQlBYrXT5UGbhGiDi/wl7qJ R5SIQjQexNVTdWNVTT192KbNNTdPwwaUUvgRQqtH0uvOCT6Wgkk44TXl6va/i0Aa63V7 +KxL5s3mbIMwcBEA2txziUQCceu0CwxpHPh6puY7pL4lKD5zBnjuRA5snjISyD0XF4JW 2Xsuxoj11yE0Cft2RcUv7KwEiET2SWdYc5RL86BdY3fdNCWgcjWfNk9qBkRgShKRLR/L HYVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780445232; x=1781050032; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=CmfRFiD30HCApEbL2wz95w04O6XoePglVU+31DCstWY=; b=NrrhZJwpO4I5MC7PdEr7dHVbjatLezjvb25hH7il0RuYw4Su8bGCnOUAKv/goCK64W et6dNOeDysiEMT1BZLy2NPplfUlVqAGPkrujKMD72orQ6CvJVS/cVDwyOGGY6r5ijfBa vBycPf0UPOuZbgTYotD188u72z5ySJcq3x9/NAJlcReyhACS9wau5wApIHX6u9BmxKvP 4B4ey7FrDgX7h1QxU/CGu0Oq2LR4Dv7KPG5mr1wBOA8yj9ISZ2MYQ7NuTj2Ev2jZHcnf TJ+Lds1pzcN9qkL8YXVceuuAjVTNFHFleeILiutWHnRTSxRIFBqa2aCkjINIWecxtY0w Pe3w== X-Gm-Message-State: AOJu0Yy1OMfP7beGHaizbdO7NiHkyL8soIK3GlLHDygQB0gbB1791sAg 4wLoyghM5WCZUbfKcelAg8f3ITLQcJTwQbvrqEKbJraaSmAieBQrsPRXFrY8o8LdSM+i1b7PzP3 9STFU X-Gm-Gg: Acq92OGb6E1kpgQo5Q4fy1U2is98UJAsclQc4ZKa9jN+d3+cm4jeX2BfaEFjksmx3LG fgeGmtIMgxjytUIldJCxavTQL5P08RwM1JpA4x3fA6GGgnbO4LcnTiBrI25xKbx1bPZ/+sGo3rX x93ht0hTrYBNPDRr+3SxLkfr6cYH65GgdOZbWAsIwrUQvaKaHA3/b9xJbN751z0pTuDTGEjHbD7 ITE9BTMWOPE74haKzsoYt0EULy9Fu5DnQl1QboWCNRMwAceKV+8xYDqcwBfCcNijIs5JlZa/vGE MOHf/KBOZ0tkKMPzePnBHwcugQErIswXgKfp7dzFaq2BNlSXUrGnXN+PJ5i923EtALCxlQCUl90 4L4XgAzzSomAHCBBBhrvqA84P8gwNGn0Hy1x7VfAZt77Y2g225R8MNQ8keaDVY+tBAK45DOtpCF ZSzEQsq3s0u3dgmMH6tAx/uhuIy9wGGEIaVFOmas5FllRbZA== X-Received: by 2002:a05:690c:940f:b0:7b1:d1af:4b93 with SMTP id 00721157ae682-7ea576c1101mr6290897b3.23.1780445231741; Tue, 02 Jun 2026 17:07:11 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:efc6:8f41:550d:2b14:9278]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7ea23a9946bsm7332207b3.37.2026.06.02.17.07.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jun 2026 17:07:11 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Anderson Nascimento , Carlos O'Donell Subject: [PATCH 4/8] Split pointer_guard.h into C and assembly headers Date: Tue, 2 Jun 2026 21:04:35 -0300 Message-ID: <20260603000656.3287796-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> References: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Move the assembly PTR_MANGLE/PTR_DEMANGLE definitions out of each pointer_guard.h into a new sibling pointer_guard-asm.h, guarded by __ASSEMBLER__. pointer_guard.h now includes pointer_guard-asm.h and keeps only the C definitions. No functional change: the .S and .c files still include pointer_guard.h and get the same macros, and resolves per-arch through the usual sysdeps include path. Checked with a build for all affected ABIs. --- sysdeps/arm/pointer_guard-asm.h | 53 +++++++++++++++ sysdeps/arm/pointer_guard.h | 37 ++--------- sysdeps/generic/pointer_guard-asm.h | 19 ++++++ sysdeps/generic/pointer_guard.h | 4 +- .../sysv/linux/aarch64/pointer_guard-asm.h | 41 ++++++++++++ .../unix/sysv/linux/aarch64/pointer_guard.h | 26 ++------ .../unix/sysv/linux/alpha/pointer_guard-asm.h | 45 +++++++++++++ sysdeps/unix/sysv/linux/alpha/pointer_guard.h | 26 +------- .../unix/sysv/linux/csky/pointer_guard-asm.h | 55 ++++++++++++++++ sysdeps/unix/sysv/linux/csky/pointer_guard.h | 38 ++--------- .../unix/sysv/linux/i386/pointer_guard-asm.h | 51 ++++++++++++++ sysdeps/unix/sysv/linux/i386/pointer_guard.h | 30 +-------- .../sysv/linux/loongarch/pointer_guard-asm.h | 52 +++++++++++++++ .../unix/sysv/linux/loongarch/pointer_guard.h | 51 ++++---------- .../sysv/linux/powerpc/pointer_guard-asm.h | 66 +++++++++++++++++++ .../unix/sysv/linux/powerpc/pointer_guard.h | 54 +-------------- .../unix/sysv/linux/s390/pointer_guard-asm.h | 42 ++++++++++++ sysdeps/unix/sysv/linux/s390/pointer_guard.h | 26 +------- .../unix/sysv/linux/sh/pointer_guard-asm.h | 64 ++++++++++++++++++ sysdeps/unix/sysv/linux/sh/pointer_guard.h | 51 +------------- .../linux/sparc/sparc32/pointer_guard-asm.h | 51 ++++++++++++++ .../sysv/linux/sparc/sparc32/pointer_guard.h | 37 +---------- .../linux/sparc/sparc64/pointer_guard-asm.h | 51 ++++++++++++++ .../sysv/linux/sparc/sparc64/pointer_guard.h | 35 +--------- .../sysv/linux/x86_64/pointer_guard-asm.h | 42 ++++++++++++ .../unix/sysv/linux/x86_64/pointer_guard.h | 30 ++------- 26 files changed, 687 insertions(+), 390 deletions(-) create mode 100644 sysdeps/arm/pointer_guard-asm.h create mode 100644 sysdeps/generic/pointer_guard-asm.h create mode 100644 sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h create mode 100644 sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h create mode 100644 sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h create mode 100644 sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h create mode 100644 sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h create mode 100644 sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h create mode 100644 sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h create mode 100644 sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h create mode 100644 sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h diff --git a/sysdeps/arm/pointer_guard-asm.h b/sysdeps/arm/pointer_guard-asm.h new file mode 100644 index 00000000000..86a9055b617 --- /dev/null +++ b/sysdeps/arm/pointer_guard-asm.h @@ -0,0 +1,53 @@ +/* Pointer guard implementation, assembly version. Arm version. + Copyright (C) 2013-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) +# define PTR_MANGLE_LOAD(guard, tmp) \ + LDR_HIDDEN (guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local), 0) +# define PTR_MANGLE(dst, src, guard, tmp) \ + PTR_MANGLE_LOAD(guard, tmp); \ + PTR_MANGLE2(dst, src, guard) +/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ +# define PTR_MANGLE2(dst, src, guard) \ + eor dst, src, guard +# define PTR_DEMANGLE(dst, src, guard, tmp) \ + PTR_MANGLE (dst, src, guard, tmp) +# define PTR_DEMANGLE2(dst, src, guard) \ + PTR_MANGLE2 (dst, src, guard) +# else +# define PTR_MANGLE_LOAD(guard, tmp) \ + LDR_GLOBAL (guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard), 0); +# define PTR_MANGLE(dst, src, guard, tmp) \ + PTR_MANGLE_LOAD(guard, tmp); \ + PTR_MANGLE2(dst, src, guard) +/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ +# define PTR_MANGLE2(dst, src, guard) \ + eor dst, src, guard +# define PTR_DEMANGLE(dst, src, guard, tmp) \ + PTR_MANGLE (dst, src, guard, tmp) +# define PTR_DEMANGLE2(dst, src, guard) \ + PTR_MANGLE2 (dst, src, guard) +# endif +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/arm/pointer_guard.h b/sysdeps/arm/pointer_guard.h index f6556a9a4af..9fa25c708a9 100644 --- a/sysdeps/arm/pointer_guard.h +++ b/sysdeps/arm/pointer_guard.h @@ -19,42 +19,15 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -/* Pointer mangling support. */ -#if (IS_IN (rtld) \ - || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) -# ifdef __ASSEMBLER__ -# define PTR_MANGLE_LOAD(guard, tmp) \ - LDR_HIDDEN (guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local), 0) -# define PTR_MANGLE(dst, src, guard, tmp) \ - PTR_MANGLE_LOAD(guard, tmp); \ - PTR_MANGLE2(dst, src, guard) -/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ -# define PTR_MANGLE2(dst, src, guard) \ - eor dst, src, guard -# define PTR_DEMANGLE(dst, src, guard, tmp) \ - PTR_MANGLE (dst, src, guard, tmp) -# define PTR_DEMANGLE2(dst, src, guard) \ - PTR_MANGLE2 (dst, src, guard) -# else +#include + +#ifndef __ASSEMBLER__ +# if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; # define PTR_MANGLE(var) \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) # define PTR_DEMANGLE(var) PTR_MANGLE (var) -# endif -#else -# ifdef __ASSEMBLER__ -# define PTR_MANGLE_LOAD(guard, tmp) \ - LDR_GLOBAL (guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard), 0); -# define PTR_MANGLE(dst, src, guard, tmp) \ - PTR_MANGLE_LOAD(guard, tmp); \ - PTR_MANGLE2(dst, src, guard) -/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ -# define PTR_MANGLE2(dst, src, guard) \ - eor dst, src, guard -# define PTR_DEMANGLE(dst, src, guard, tmp) \ - PTR_MANGLE (dst, src, guard, tmp) -# define PTR_DEMANGLE2(dst, src, guard) \ - PTR_MANGLE2 (dst, src, guard) # else # include extern uintptr_t __pointer_chk_guard attribute_relro; diff --git a/sysdeps/generic/pointer_guard-asm.h b/sysdeps/generic/pointer_guard-asm.h new file mode 100644 index 00000000000..bdfd06b92d1 --- /dev/null +++ b/sysdeps/generic/pointer_guard-asm.h @@ -0,0 +1,19 @@ +/* Pointer obfuscation implementation, assembly version. Generic (no-op). + Copyright (C) 2022-2026 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 + . */ + +/* Assembler definitions for pointer obfuscation, if the ABI required it. */ diff --git a/sysdeps/generic/pointer_guard.h b/sysdeps/generic/pointer_guard.h index 9d7a1f51a51..49eb5ca4ba2 100644 --- a/sysdeps/generic/pointer_guard.h +++ b/sysdeps/generic/pointer_guard.h @@ -19,8 +19,8 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -/* Assembler code depends on PTR_MANGLE not being defined for - optimization purposes. */ +#include + #ifndef __ASSEMBLER__ # define PTR_MANGLE(x) (void) (x) # define PTR_DEMANGLE(x) (void) (x) diff --git a/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h new file mode 100644 index 00000000000..ed483a806a6 --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h @@ -0,0 +1,41 @@ +/* Pointer guard implementation, assembly version. AArch64 version. + Copyright (C) 2014-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) \ + || IS_IN (libpthread)))) +# define PTR_MANGLE(dst, src, tmp) \ + adrp tmp, C_SYMBOL_NAME(__pointer_chk_guard_local); \ + ldr tmp, [tmp, :lo12:C_SYMBOL_NAME(__pointer_chk_guard_local)]; \ + eor dst, src, tmp +# define PTR_DEMANGLE(dst, src, tmp) PTR_MANGLE (dst, src, tmp) +# else +# define PTR_MANGLE(dst, src, tmp) \ + adrp tmp, :got:C_SYMBOL_NAME(__pointer_chk_guard); \ + ldr tmp, [tmp, :got_lo12:C_SYMBOL_NAME(__pointer_chk_guard)]; \ + ldr tmp, [tmp]; \ + eor dst, src, tmp; +# define PTR_DEMANGLE(dst, src, tmp) PTR_MANGLE (dst, src, tmp) +# endif +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h b/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h index 4689f29184d..7b7d8b0b714 100644 --- a/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h @@ -19,30 +19,16 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -/* Pointer mangling is supported for AArch64. */ -#if (IS_IN (rtld) \ - || (!defined SHARED && (IS_IN (libc) \ - || IS_IN (libpthread)))) -# ifdef __ASSEMBLER__ -# define PTR_MANGLE(dst, src, tmp) \ - adrp tmp, C_SYMBOL_NAME(__pointer_chk_guard_local); \ - ldr tmp, [tmp, :lo12:C_SYMBOL_NAME(__pointer_chk_guard_local)]; \ - eor dst, src, tmp -# define PTR_DEMANGLE(dst, src, tmp) PTR_MANGLE (dst, src, tmp) -# else +#include + +#ifndef __ASSEMBLER__ +# if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) \ + || IS_IN (libpthread)))) extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; # define PTR_MANGLE(var) \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) # define PTR_DEMANGLE(var) PTR_MANGLE (var) -# endif -#else -# ifdef __ASSEMBLER__ -# define PTR_MANGLE(dst, src, tmp) \ - adrp tmp, :got:C_SYMBOL_NAME(__pointer_chk_guard); \ - ldr tmp, [tmp, :got_lo12:C_SYMBOL_NAME(__pointer_chk_guard)]; \ - ldr tmp, [tmp]; \ - eor dst, src, tmp; -# define PTR_DEMANGLE(dst, src, tmp) PTR_MANGLE (dst, src, tmp) # else # include extern uintptr_t __pointer_chk_guard attribute_relro; diff --git a/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h new file mode 100644 index 00000000000..15f9e6cacef --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h @@ -0,0 +1,45 @@ +/* Pointer guard implementation, assembly version. Alpha version. + Copyright (C) 2006-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# if IS_IN (rtld) +# define PTR_MANGLE(dst, src, tmp) \ + ldah tmp, __pointer_chk_guard_local($29) !gprelhigh; \ + ldq tmp, __pointer_chk_guard_local(tmp) !gprellow; \ + xor src, tmp, dst +# define PTR_MANGLE2(dst, src, tmp) \ + xor src, tmp, dst +# elif defined SHARED +# define PTR_MANGLE(dst, src, tmp) \ + ldq tmp, __pointer_chk_guard; \ + xor src, tmp, dst +# else +# define PTR_MANGLE(dst, src, tmp) \ + ldq tmp, __pointer_chk_guard_local; \ + xor src, tmp, dst +# endif +# define PTR_MANGLE2(dst, src, tmp) \ + xor src, tmp, dst +# define PTR_DEMANGLE(dst, tmp) PTR_MANGLE(dst, dst, tmp) +# define PTR_DEMANGLE2(dst, tmp) PTR_MANGLE2(dst, dst, tmp) +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/alpha/pointer_guard.h b/sysdeps/unix/sysv/linux/alpha/pointer_guard.h index f799399e754..0741bf7a183 100644 --- a/sysdeps/unix/sysv/linux/alpha/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/alpha/pointer_guard.h @@ -19,31 +19,9 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -/* Pointer mangling support. Note that tls access is slow enough that - we don't deoptimize things by placing the pointer check value there. */ +#include -#ifdef __ASSEMBLER__ -# if IS_IN (rtld) -# define PTR_MANGLE(dst, src, tmp) \ - ldah tmp, __pointer_chk_guard_local($29) !gprelhigh; \ - ldq tmp, __pointer_chk_guard_local(tmp) !gprellow; \ - xor src, tmp, dst -# define PTR_MANGLE2(dst, src, tmp) \ - xor src, tmp, dst -# elif defined SHARED -# define PTR_MANGLE(dst, src, tmp) \ - ldq tmp, __pointer_chk_guard; \ - xor src, tmp, dst -# else -# define PTR_MANGLE(dst, src, tmp) \ - ldq tmp, __pointer_chk_guard_local; \ - xor src, tmp, dst -# endif -# define PTR_MANGLE2(dst, src, tmp) \ - xor src, tmp, dst -# define PTR_DEMANGLE(dst, tmp) PTR_MANGLE(dst, dst, tmp) -# define PTR_DEMANGLE2(dst, tmp) PTR_MANGLE2(dst, dst, tmp) -#else +#ifndef __ASSEMBLER__ # include # if (IS_IN (rtld) \ || (!defined SHARED && (IS_IN (libc) \ diff --git a/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h new file mode 100644 index 00000000000..8eb6d2c1d42 --- /dev/null +++ b/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h @@ -0,0 +1,55 @@ +/* Pointer obfuscation implementation, assembly version. C-SKY version. + Copyright (C) 2022-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) +# define PTR_MANGLE(dst, src, guard) \ + grs t0, 1f; \ +1: \ + lrw guard, 1b@GOTPC; \ + addu t0, guard; \ + lrw guard, __pointer_chk_guard_local@GOT; \ + ldr.w guard, (t0, guard << 0); \ + ldw guard, (guard, 0); \ + xor dst, src, guard; +# define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard) +# define PTR_MANGLE2(dst, src, guard) \ + xor dst, src, guard +# define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard) +# else +# define PTR_MANGLE(dst, src, guard) \ + grs t0, 1f; \ +1: \ + lrw guard, 1b@GOTPC; \ + addu t0, guard; \ + lrw guard, __pointer_chk_guard@GOT; \ + ldr.w guard, (t0, guard << 0); \ + ldw guard, (guard, 0); \ + xor dst, src, guard; +# define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard) +# define PTR_MANGLE2(dst, src, guard) \ + xor dst, src, guard +# define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard) +# endif +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/csky/pointer_guard.h b/sysdeps/unix/sysv/linux/csky/pointer_guard.h index cdb3917481a..2aa044bdc42 100644 --- a/sysdeps/unix/sysv/linux/csky/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/csky/pointer_guard.h @@ -19,43 +19,15 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if (IS_IN (rtld) \ - || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) -# ifdef __ASSEMBLER__ -# define PTR_MANGLE(dst, src, guard) \ - grs t0, 1f; \ -1: \ - lrw guard, 1b@GOTPC; \ - addu t0, guard; \ - lrw guard, __pointer_chk_guard_local@GOT; \ - ldr.w guard, (t0, guard << 0); \ - ldw guard, (guard, 0); \ - xor dst, src, guard; -# define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard) -# define PTR_MANGLE2(dst, src, guard) \ - xor dst, src, guard -# define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard) -# else +#include + +#ifndef __ASSEMBLER__ +# if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) extern uintptr_t __pointer_chk_guard_local; # define PTR_MANGLE(var) \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) # define PTR_DEMANGLE(var) PTR_MANGLE (var) -# endif -#else -# ifdef __ASSEMBLER__ -# define PTR_MANGLE(dst, src, guard) \ - grs t0, 1f; \ -1: \ - lrw guard, 1b@GOTPC; \ - addu t0, guard; \ - lrw guard, __pointer_chk_guard@GOT; \ - ldr.w guard, (t0, guard << 0); \ - ldw guard, (guard, 0); \ - xor dst, src, guard; -# define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard) -# define PTR_MANGLE2(dst, src, guard) \ - xor dst, src, guard -# define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard) # else # include extern uintptr_t __pointer_chk_guard; diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h new file mode 100644 index 00000000000..19ee959e8fd --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h @@ -0,0 +1,51 @@ +/* Pointer obfuscation implementation, assembly version. i386 version. + Copyright (C) 2005-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# include + +# if IS_IN (rtld) || !defined SHARED +# ifdef PIC +# define PTR_MANGLE(reg) LOAD_PIC_REG (bx); \ + xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg; \ + roll $9, reg +# define PTR_DEMANGLE(reg) rorl $9, reg; \ + LOAD_PIC_REG (bx); \ + xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg +# else +# define PTR_MANGLE(reg) xorl __pointer_chk_guard_local, reg; \ + roll $9, reg +# define PTR_DEMANGLE(reg) rorl $9, reg; \ + xorl __pointer_chk_guard_local, reg +# endif +# else +# define PTR_MANGLE(reg) LOAD_PIC_REG (bx); \ + movl __pointer_chk_guard@GOT(%ebx), %esi; \ + xorl (%esi), reg; \ + roll $9, reg +# define PTR_DEMANGLE(reg) rorl $9, reg; \ + LOAD_PIC_REG (bx); \ + movl __pointer_chk_guard@GOT(%ebx), %esi; \ + xorl (%esi), reg +# endif +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard.h b/sysdeps/unix/sysv/linux/i386/pointer_guard.h index 63308d84e76..7776c282d81 100644 --- a/sysdeps/unix/sysv/linux/i386/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/i386/pointer_guard.h @@ -19,33 +19,9 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#ifdef __ASSEMBLER__ -# include -# if IS_IN (rtld) || !defined SHARED -# ifdef PIC -# define PTR_MANGLE(reg) LOAD_PIC_REG (bx); \ - xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg; \ - roll $9, reg -# define PTR_DEMANGLE(reg) rorl $9, reg; \ - LOAD_PIC_REG (bx); \ - xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg -# else -# define PTR_MANGLE(reg) xorl __pointer_chk_guard_local, reg; \ - roll $9, reg -# define PTR_DEMANGLE(reg) rorl $9, reg; \ - xorl __pointer_chk_guard_local, reg -# endif -# else -# define PTR_MANGLE(reg) LOAD_PIC_REG (bx); \ - movl __pointer_chk_guard@GOT(%ebx), %esi; \ - xorl (%esi), reg; \ - roll $9, reg -# define PTR_DEMANGLE(reg) rorl $9, reg; \ - LOAD_PIC_REG (bx); \ - movl __pointer_chk_guard@GOT(%ebx), %esi; \ - xorl (%esi), reg -# endif -#else +#include + +#ifndef __ASSEMBLER__ # include # include # if IS_IN (rtld) || !defined SHARED diff --git a/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h new file mode 100644 index 00000000000..ac55dd8c95c --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h @@ -0,0 +1,52 @@ +/* Pointer obfuscation implementation, assembly version. LoongArch version. + Copyright (C) 2022-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) \ + || IS_IN (libpthread)))) +# define PTR_MANGLE(dst, src, guard) \ + LOAD_LOCAL (guard, __pointer_chk_guard_local); \ + PTR_MANGLE2 (dst, src, guard); +# define PTR_DEMANGLE(dst, src, guard) \ + LOAD_LOCAL (guard, __pointer_chk_guard_local); \ + PTR_DEMANGLE2 (dst, src, guard); +/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ +# define PTR_MANGLE2(dst, src, guard) \ + xor dst, src, guard; +# define PTR_DEMANGLE2(dst, src, guard) \ + PTR_MANGLE2 (dst, src, guard); +# else +# define PTR_MANGLE(dst, src, guard) \ + LOAD_GLOBAL (guard, __pointer_chk_guard); \ + PTR_MANGLE2 (dst, src, guard); +# define PTR_DEMANGLE(dst, src, guard) \ + LOAD_GLOBAL (guard, __pointer_chk_guard); \ + PTR_DEMANGLE2 (dst, src, guard); +/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ +# define PTR_MANGLE2(dst, src, guard) \ + xor dst, src, guard; +# define PTR_DEMANGLE2(dst, src, guard) \ + PTR_MANGLE2 (dst, src, guard); +# endif +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h b/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h index 69150c0211f..c080bdd0a9d 100644 --- a/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h @@ -19,52 +19,23 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if (IS_IN (rtld) \ - || (!defined SHARED && (IS_IN (libc) \ - || IS_IN (libpthread)))) +#include -#ifdef __ASSEMBLER__ -#define PTR_MANGLE(dst, src, guard) \ - LOAD_LOCAL (guard, __pointer_chk_guard_local); \ - PTR_MANGLE2 (dst, src, guard); -#define PTR_DEMANGLE(dst, src, guard) \ - LOAD_LOCAL (guard, __pointer_chk_guard_local); \ - PTR_DEMANGLE2 (dst, src, guard); -/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ -#define PTR_MANGLE2(dst, src, guard) \ - xor dst, src, guard; -#define PTR_DEMANGLE2(dst, src, guard) \ - PTR_MANGLE2 (dst, src, guard); -#else +#ifndef __ASSEMBLER__ # include +# if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) \ + || IS_IN (libpthread)))) extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -#define PTR_MANGLE(var) \ +# define PTR_MANGLE(var) \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -#define PTR_DEMANGLE(var) PTR_MANGLE (var) -#endif - -#else - -#ifdef __ASSEMBLER__ -#define PTR_MANGLE(dst, src, guard) \ - LOAD_GLOBAL (guard, __pointer_chk_guard); \ - PTR_MANGLE2 (dst, src, guard); -#define PTR_DEMANGLE(dst, src, guard) \ - LOAD_GLOBAL (guard, __pointer_chk_guard); \ - PTR_DEMANGLE2 (dst, src, guard); -/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ -#define PTR_MANGLE2(dst, src, guard) \ - xor dst, src, guard; -#define PTR_DEMANGLE2(dst, src, guard) \ - PTR_MANGLE2 (dst, src, guard); -#else -# include +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# else extern uintptr_t __pointer_chk_guard attribute_relro; -#define PTR_MANGLE(var) \ +# define PTR_MANGLE(var) \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -#define PTR_DEMANGLE(var) PTR_MANGLE (var) -#endif - +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h new file mode 100644 index 00000000000..ca4278cc00a --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h @@ -0,0 +1,66 @@ +/* Pointer obfuscation implementation, assembly version. PowerPC version. + Copyright (C) 2005-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# include + +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif + +# if defined(__PPC64__) || defined(__powerpc64__) +# define PTR_GUARD_LOAD(tmpreg) \ + addis tmpreg,r2,PTR_GUARD_SYM@got@ha; \ + ld tmpreg,PTR_GUARD_SYM@got@l(tmpreg); \ + ld tmpreg,0(tmpreg) +# elif defined PIC +# define PTR_GUARD_LOAD(tmpreg) \ + mflr r12; \ + bcl 20,31,0f; \ +0: mflr tmpreg; \ + addis tmpreg,tmpreg,_GLOBAL_OFFSET_TABLE_-0b@ha; \ + addi tmpreg,tmpreg,_GLOBAL_OFFSET_TABLE_-0b@l; \ + mtlr r12; \ + lwz tmpreg,PTR_GUARD_SYM@got(tmpreg); \ + lwz tmpreg,0(tmpreg) +# else +/* Position-dependent 32-bit code can address the variable directly. */ +# define PTR_GUARD_LOAD(tmpreg) \ + lis tmpreg,PTR_GUARD_SYM@ha; \ + lwz tmpreg,PTR_GUARD_SYM@l(tmpreg) +# endif + +# define PTR_MANGLE(reg, tmpreg) \ + PTR_GUARD_LOAD (tmpreg); \ + xor reg,tmpreg,reg +# define PTR_MANGLE2(reg, tmpreg) \ + xor reg,tmpreg,reg +# define PTR_MANGLE3(destreg, reg, tmpreg) \ + PTR_GUARD_LOAD (tmpreg); \ + xor destreg,tmpreg,reg +# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) +# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) +# define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg) +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h index 271cf93c2f4..51f588ec11c 100644 --- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h @@ -19,59 +19,9 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -/* In ld.so and in statically linked programs the guard is the module-local - relro variable __pointer_chk_guard_local; in other shared objects it is - the global __pointer_chk_guard provided by the dynamic loader. */ -#ifdef __ASSEMBLER__ -# include -# if IS_IN (rtld) || !defined SHARED -# define PTR_GUARD_SYM __pointer_chk_guard_local -# else -# define PTR_GUARD_SYM __pointer_chk_guard -# endif +#include -# if defined(__PPC64__) || defined(__powerpc64__) -/* r2 (the TOC pointer) is always available, so load the guard's address - from the TOC/GOT and dereference it. */ -# define PTR_GUARD_LOAD(tmpreg) \ - addis tmpreg,r2,PTR_GUARD_SYM@got@ha; \ - ld tmpreg,PTR_GUARD_SYM@got@l(tmpreg); \ - ld tmpreg,0(tmpreg) -# elif defined PIC -/* Position-independent 32-bit code has no dedicated GOT register here, so - establish one with the usual bcl/mflr sequence. GAS numeric local labels - are used so the sequence can be expanded more than once per file. LR is - clobbered by the bcl, so it is saved in r12 (a volatile register that is - not otherwise live at the mangling points) and restored; r0 must not be - used here as it holds the saved link register in __longjmp. */ -# define PTR_GUARD_LOAD(tmpreg) \ - mflr r12; \ - bcl 20,31,0f; \ -0: mflr tmpreg; \ - addis tmpreg,tmpreg,_GLOBAL_OFFSET_TABLE_-0b@ha; \ - addi tmpreg,tmpreg,_GLOBAL_OFFSET_TABLE_-0b@l; \ - mtlr r12; \ - lwz tmpreg,PTR_GUARD_SYM@got(tmpreg); \ - lwz tmpreg,0(tmpreg) -# else -/* Position-dependent 32-bit code can address the variable directly. */ -# define PTR_GUARD_LOAD(tmpreg) \ - lis tmpreg,PTR_GUARD_SYM@ha; \ - lwz tmpreg,PTR_GUARD_SYM@l(tmpreg) -# endif - -# define PTR_MANGLE(reg, tmpreg) \ - PTR_GUARD_LOAD (tmpreg); \ - xor reg,tmpreg,reg -# define PTR_MANGLE2(reg, tmpreg) \ - xor reg,tmpreg,reg -# define PTR_MANGLE3(destreg, reg, tmpreg) \ - PTR_GUARD_LOAD (tmpreg); \ - xor destreg,tmpreg,reg -# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) -# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) -# define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg) -#else +#ifndef __ASSEMBLER__ # include # if IS_IN (rtld) || !defined SHARED extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h new file mode 100644 index 00000000000..71cc0465d13 --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h @@ -0,0 +1,42 @@ +/* Pointer obfuscation implementation, assembly version. s390x version. + Copyright (C) 2005-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_LOAD(tmpreg) \ + larl tmpreg,__pointer_chk_guard_local; \ + lg tmpreg,0(tmpreg) +# else +# define PTR_GUARD_LOAD(tmpreg) \ + larl tmpreg,__pointer_chk_guard@GOTENT; \ + lg tmpreg,0(tmpreg); \ + lg tmpreg,0(tmpreg) +# endif +# define PTR_MANGLE(reg, tmpreg) \ + PTR_GUARD_LOAD (tmpreg); \ + xgr reg,tmpreg +# define PTR_MANGLE2(reg, tmpreg) \ + xgr reg,tmpreg +# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) +# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard.h b/sysdeps/unix/sysv/linux/s390/pointer_guard.h index a4ec92f6655..403eff63282 100644 --- a/sysdeps/unix/sysv/linux/s390/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/s390/pointer_guard.h @@ -19,29 +19,9 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -/* In ld.so and in statically linked programs the guard is the module-local - relro variable __pointer_chk_guard_local, reached PC-relatively with larl; - in other shared objects it is the global __pointer_chk_guard provided by - the dynamic loader, reached through the GOT. */ -#ifdef __ASSEMBLER__ -# if IS_IN (rtld) || !defined SHARED -# define PTR_GUARD_LOAD(tmpreg) \ - larl tmpreg,__pointer_chk_guard_local; \ - lg tmpreg,0(tmpreg) -# else -# define PTR_GUARD_LOAD(tmpreg) \ - larl tmpreg,__pointer_chk_guard@GOTENT; \ - lg tmpreg,0(tmpreg); \ - lg tmpreg,0(tmpreg) -# endif -# define PTR_MANGLE(reg, tmpreg) \ - PTR_GUARD_LOAD (tmpreg); \ - xgr reg,tmpreg -# define PTR_MANGLE2(reg, tmpreg) \ - xgr reg,tmpreg -# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) -# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) -#else +#include + +#ifndef __ASSEMBLER__ # include # if IS_IN (rtld) || !defined SHARED extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h new file mode 100644 index 00000000000..64e6f6153e8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h @@ -0,0 +1,64 @@ +/* Pointer obfuscation implementation, assembly version. SH version. + Copyright (C) 2005-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif +# ifdef PIC +# define PTR_GUARD_LOAD(tmp) \ + mov r0, r3; \ + mova .Lptrg_got, r0; \ + mov.l .Lptrg_got, tmp; \ + add r0, tmp; \ + mov.l .Lptrg_sym, r0; \ + mov.l @(r0, tmp), tmp; \ + mov r3, r0; \ + mov.l @tmp, tmp; \ + bra .Lptrg_end; \ + nop; \ + .align 2; \ +.Lptrg_got: \ + .long _GLOBAL_OFFSET_TABLE_; \ +.Lptrg_sym: \ + .long PTR_GUARD_SYM@GOT; \ +.Lptrg_end: +# else +# define PTR_GUARD_LOAD(tmp) \ + mov.l .Lptrg_sym, tmp; \ + mov.l @tmp, tmp; \ + bra .Lptrg_end; \ + nop; \ + .align 2; \ +.Lptrg_sym: \ + .long PTR_GUARD_SYM; \ +.Lptrg_end: +# endif +# define PTR_MANGLE(reg, tmp) \ + PTR_GUARD_LOAD (tmp); xor tmp,reg +# define PTR_MANGLE2(reg, tmp) xor tmp,reg +# define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp) +# define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp) +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard.h b/sysdeps/unix/sysv/linux/sh/pointer_guard.h index 9a1e01a452c..42340faca83 100644 --- a/sysdeps/unix/sysv/linux/sh/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sh/pointer_guard.h @@ -19,54 +19,9 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -/* In ld.so and in statically linked programs the guard is the module-local - relro variable __pointer_chk_guard_local; in other shared objects it is - the global __pointer_chk_guard provided by the dynamic loader. */ -#ifdef __ASSEMBLER__ -# if IS_IN (rtld) || !defined SHARED -# define PTR_GUARD_SYM __pointer_chk_guard_local -# else -# define PTR_GUARD_SYM __pointer_chk_guard -# endif -# ifdef PIC -/* Load the guard through the GOT. The GOT pointer is computed with the - usual mova/mov.l sequence which clobbers r0; in __longjmp r0 holds the - return value, so it is saved in r3 (dead at every mangling site) and - restored. A literal pool is emitted inline and branched over. */ -# define PTR_GUARD_LOAD(tmp) \ - mov r0, r3; \ - mova .Lptrg_got, r0; \ - mov.l .Lptrg_got, tmp; \ - add r0, tmp; \ - mov.l .Lptrg_sym, r0; \ - mov.l @(r0, tmp), tmp; \ - mov r3, r0; \ - mov.l @tmp, tmp; \ - bra .Lptrg_end; \ - nop; \ - .align 2; \ -.Lptrg_got: \ - .long _GLOBAL_OFFSET_TABLE_; \ -.Lptrg_sym: \ - .long PTR_GUARD_SYM@GOT; \ -.Lptrg_end: -# else -# define PTR_GUARD_LOAD(tmp) \ - mov.l .Lptrg_sym, tmp; \ - mov.l @tmp, tmp; \ - bra .Lptrg_end; \ - nop; \ - .align 2; \ -.Lptrg_sym: \ - .long PTR_GUARD_SYM; \ -.Lptrg_end: -# endif -# define PTR_MANGLE(reg, tmp) \ - PTR_GUARD_LOAD (tmp); xor tmp,reg -# define PTR_MANGLE2(reg, tmp) xor tmp,reg -# define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp) -# define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp) -#else +#include + +#ifndef __ASSEMBLER__ # include # if IS_IN (rtld) || !defined SHARED extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h new file mode 100644 index 00000000000..e1e42f8087a --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h @@ -0,0 +1,51 @@ +/* Pointer obfuscation implementation, assembly version. 32-bit SPARC version. + Copyright (C) 2006-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# include + +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif +# ifdef PIC +# define PTR_GUARD_LOAD(tmpreg) \ + SETUP_PIC_REG_LEAF(o2, o3); \ + sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ + xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ + ld [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ + ld [tmpreg], tmpreg +# else +# define PTR_GUARD_LOAD(tmpreg) \ + sethi %hi(PTR_GUARD_SYM), tmpreg; \ + ld [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg +# endif +# define PTR_MANGLE(dreg, reg, tmpreg) \ + PTR_GUARD_LOAD (tmpreg); \ + xor reg, tmpreg, dreg +# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) +# define PTR_MANGLE2(dreg, reg, tmpreg) \ + xor reg, tmpreg, dreg +# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h index 2242981f6bd..86d3fbb7d27 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h @@ -19,40 +19,9 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -/* In ld.so and in statically linked programs the guard is the module-local - relro variable __pointer_chk_guard_local; in other shared objects it is - the global __pointer_chk_guard provided by the dynamic loader. */ -#ifdef __ASSEMBLER__ -# include -# if IS_IN (rtld) || !defined SHARED -# define PTR_GUARD_SYM __pointer_chk_guard_local -# else -# define PTR_GUARD_SYM __pointer_chk_guard -# endif -# ifdef PIC -/* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT - pointer in %o2 while preserving %o7 (the return address, which setjmp - mangles), using %o3 as a scratch register; both are dead at every - mangling site. */ -# define PTR_GUARD_LOAD(tmpreg) \ - SETUP_PIC_REG_LEAF(o2, o3); \ - sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ - xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ - ld [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ - ld [tmpreg], tmpreg -# else -# define PTR_GUARD_LOAD(tmpreg) \ - sethi %hi(PTR_GUARD_SYM), tmpreg; \ - ld [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg -# endif -# define PTR_MANGLE(dreg, reg, tmpreg) \ - PTR_GUARD_LOAD (tmpreg); \ - xor reg, tmpreg, dreg -# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) -# define PTR_MANGLE2(dreg, reg, tmpreg) \ - xor reg, tmpreg, dreg -# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) -#else +#include + +#ifndef __ASSEMBLER__ # include # if IS_IN (rtld) || !defined SHARED extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h new file mode 100644 index 00000000000..f378c88e58c --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h @@ -0,0 +1,51 @@ +/* Pointer obfuscation implementation, assembly version. 64-bit SPARC version. + Copyright (C) 2006-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# include + +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif +# ifdef PIC +# define PTR_GUARD_LOAD(tmpreg) \ + SETUP_PIC_REG_LEAF(o2, o3); \ + sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ + xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ + ldx [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ + ldx [tmpreg], tmpreg +# else +# define PTR_GUARD_LOAD(tmpreg) \ + sethi %hi(PTR_GUARD_SYM), tmpreg; \ + ldx [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg +# endif +# define PTR_MANGLE(dreg, reg, tmpreg) \ + PTR_GUARD_LOAD (tmpreg); \ + xor reg, tmpreg, dreg +# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) +# define PTR_MANGLE2(dreg, reg, tmpreg) \ + xor reg, tmpreg, dreg +# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h index 8cdb2edf7be..fc0a723905e 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h @@ -19,38 +19,9 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -/* In ld.so and in statically linked programs the guard is the module-local - relro variable __pointer_chk_guard_local; in other shared objects it is - the global __pointer_chk_guard provided by the dynamic loader. */ -#ifdef __ASSEMBLER__ -# include -# if IS_IN (rtld) || !defined SHARED -# define PTR_GUARD_SYM __pointer_chk_guard_local -# else -# define PTR_GUARD_SYM __pointer_chk_guard -# endif -# ifdef PIC -/* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT - pointer in %o2 while preserving %o7, using %o3 as a scratch register. */ -# define PTR_GUARD_LOAD(tmpreg) \ - SETUP_PIC_REG_LEAF(o2, o3); \ - sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ - xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ - ldx [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ - ldx [tmpreg], tmpreg -# else -# define PTR_GUARD_LOAD(tmpreg) \ - sethi %hi(PTR_GUARD_SYM), tmpreg; \ - ldx [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg -# endif -# define PTR_MANGLE(dreg, reg, tmpreg) \ - PTR_GUARD_LOAD (tmpreg); \ - xor reg, tmpreg, dreg -# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) -# define PTR_MANGLE2(dreg, reg, tmpreg) \ - xor reg, tmpreg, dreg -# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) -#else +#include + +#ifndef __ASSEMBLER__ # include # if IS_IN (rtld) || !defined SHARED extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h new file mode 100644 index 00000000000..11b0ea3f83b --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h @@ -0,0 +1,42 @@ +/* Pointer obfuscation implementation, assembly version. x86-64 version. + Copyright (C) 2005-2026 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 POINTER_GUARD_ASM_H +#define POINTER_GUARD_ASM_H + +#ifdef __ASSEMBLER__ +# include +# include + +# if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) +# define PTR_MANGLE(reg) xor __pointer_chk_guard_local(%rip), reg; \ + rol $2*LP_SIZE+1, reg +# define PTR_DEMANGLE(reg) ror $2*LP_SIZE+1, reg; \ + xor __pointer_chk_guard_local(%rip), reg +# else +# define PTR_MANGLE(reg) mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP; \ + xor (%R11_LP), reg; \ + rol $2*LP_SIZE+1, reg +# define PTR_DEMANGLE(reg) ror $2*LP_SIZE+1, reg; \ + mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP; \ + xor (%R11_LP), reg +# endif +#endif + +#endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h index 6d09b429cd2..dd3a9752b2a 100644 --- a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h @@ -19,19 +19,14 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#include -#include +#include -#if (IS_IN (rtld) \ - || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) -# ifdef __ASSEMBLER__ -# define PTR_MANGLE(reg) xor __pointer_chk_guard_local(%rip), reg; \ - rol $2*LP_SIZE+1, reg -# define PTR_DEMANGLE(reg) ror $2*LP_SIZE+1, reg; \ - xor __pointer_chk_guard_local(%rip), reg -# else -# include -# include +#ifndef __ASSEMBLER__ +# include +# include + +# if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; # define PTR_MANGLE(var) \ do { \ @@ -47,18 +42,7 @@ extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; (var) = (__typeof (var)) ((uintptr_t) (var) \ ^ __pointer_chk_guard_local); \ } while (0) -# endif -#else -# ifdef __ASSEMBLER__ -# define PTR_MANGLE(reg) mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP;\ - xor (%R11_LP), reg; \ - rol $2*LP_SIZE+1, reg -# define PTR_DEMANGLE(reg) ror $2*LP_SIZE+1, reg; \ - mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP;\ - xor (%R11_LP), reg # else -# include -# include extern uintptr_t __pointer_chk_guard attribute_relro; # define PTR_MANGLE(var) \ do { \ From patchwork Wed Jun 3 00:04:36 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 136335 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D99764BA2E2C for ; Wed, 3 Jun 2026 00:08:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D99764BA2E2C Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=aI9k1nsC X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-yw1-x1131.google.com (mail-yw1-x1131.google.com [IPv6:2607:f8b0:4864:20::1131]) by sourceware.org (Postfix) with ESMTPS id 4B7F74BA2E20 for ; Wed, 3 Jun 2026 00:07:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4B7F74BA2E20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4B7F74BA2E20 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1131 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445235; cv=none; b=GBVUV4mUjMkSC0voUFb7sgmqnn5tAtWiz8yzViKrve/rS3as/oepeYAImhrYNbDMJ30rG/hF/Lag8Jo/wbnLSa47/x2VrbxnouHBN1hlMwsHqu8+6Iiom0ccd+pdEDAjwRvonfIBXVKxvWcVyuqdkZ72DbsQA+SrroyKcfjTdwo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445235; c=relaxed/simple; bh=p0Q6ztW3+cP8oSs2z1t8KNMBCmcHi2TRaTHOQawkwSE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=QqtwzIm+D/cAlB7WdDyLXNtuVR8KMTexrLRGb5Vf1jd2SMw7oDXpoh89t+XlUWmzbldL6RcRx2JUkC5nGP9d1fOA5x8QHYjnnYDWiCj0c1hsYkRgCRUKYKAOTye5UhBjia0fFXWFNWF5UBmOA8Xvb7MVLt+KD/QQhVCPhC/juCQ= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=aI9k1nsC DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4B7F74BA2E20 Received: by mail-yw1-x1131.google.com with SMTP id 00721157ae682-7dbd25309f7so64305127b3.2 for ; Tue, 02 Jun 2026 17:07:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1780445235; x=1781050035; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=oZyaAU0t997oCtxvx70UWvbrioS5de9pe/ta3uQCNGc=; b=aI9k1nsC2nyU9UTe2v6X3THPcvipHuUuEjWhuca/qmY6fJHyKg5xWOIsCuFSbsr6du mUea6I4RBv1wqb9jPFbu0hGe+iPwcKcBDe2pkQgbN7jAAqbreC+kQg+b7Keu5DUx67aw lDlkxjpPFg7d+QFL/XVgDX0vpexNZ2dfVNB6/QNUhC7XwnAGUQb5qTNBq+Ts1I4Hl5oK xVU4UU0alITGD5CCUIt11iXD7eRd3J1yifypuDWHvHWUigWDXmskIji20bPx3SgfpDJs kogYkhc+wO4EnYhv06XdheDgKiB3Mh3mXmGho2LKutIfxbGw7zaYwlYW3nFf2RdZ92tm bK+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780445235; x=1781050035; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=oZyaAU0t997oCtxvx70UWvbrioS5de9pe/ta3uQCNGc=; b=j5WUSQgQk3pg1gEygRu/qwVULbLNRgT92l05GfSOjpeaUwfIJ0JfCJDRCcoE7cecta oY+n70wtk9AavxH2SIVmfCjPcv73fXoO67pIo5uonMskot11iV2+6MY5Si14MdMjGuCB dQSJeq2DEz/dy7qHREzJhBfgNWOs0cGR1zw1H2g7pRXfKChVWZ8LfnI9FhPVykA4eItc nCAFhPQKwsC2xy7bQX3btT6ZicJJqjMCtzdlNsIpKtLvRWbsEIq9JpxrhBlPC9x0s8Kf KPgBPCbpDXk52Uj7Ax9Ff2SCKvn5y4DUElMsL0vZhLt8CDOIl2jKYylTwCXLHV5FYghk sWvw== X-Gm-Message-State: AOJu0Yz2+RwfqG7WH246e6M8R7pTQM8z57nW54TRfl2WwNJZOtGEKa73 Ig4zQ0JbCXN/qtHxbm4ODyj7Mb5pQl4G+r1FuB6opdNDLPkHHTQO3KKghOYvM9BFo+KBCoB/J90 Wol/x X-Gm-Gg: Acq92OH+7eSIuhiTTEySb30mLmS8mma7Vra+SGouX5rgkGAW2+pSEHJ7rZvjlikBp5Y L0pCrqoay32zobUYNwCm//DFgfaVHLKaoIOP/a8vbgf5YlbMEuGDYZpFZwk9zMsqnEE/cJBfqe0 sqj5rSbHcxgTJzWBO7enWf4xYXCOPWKNXeXsoC0PwOpDUo4GFTuna7NZNstHdnDJoG2I8+7q09q SQWwt5lsJIbdwUWqERtDdPQCRX/y5rPUZM21+iGfKmecfggAB8pm33e2oZ0u9Ph4fidylkwefwr A3FCeUVFlN/qFPih6f5LU8pVbeat3rzR7OOEtTqo2ZvHXjeg6xoaN9cZBBGmaiaUCavDfvLV52V VqcFwHsaf37VlbKOcRPavIpq5CcBm2/ejxbA5miePeqxz2wpKj7ZBfK2sbfE1rgW22u9es6gL6x iXuoFOOqHiO6ouG12Ft5VsmoECRmCV6Kbap4SNLiu4aUgmgIMqQCHjD5Zc X-Received: by 2002:a05:690c:600f:b0:7ba:f690:70be with SMTP id 00721157ae682-7ea49872b63mr12081247b3.7.1780445234291; Tue, 02 Jun 2026 17:07:14 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:efc6:8f41:550d:2b14:9278]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7ea23a9946bsm7332207b3.37.2026.06.02.17.07.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jun 2026 17:07:13 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Anderson Nascimento , Carlos O'Donell Subject: [PATCH 5/8] Consolidate the C pointer guard implementation into the generic header Date: Tue, 2 Jun 2026 21:04:36 -0300 Message-ID: <20260603000656.3287796-6-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> References: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org All the per-architecture pointer_guard.h files implemented the same C PTR_MANGLE/PTR_DEMANGLE (an exclusive-or by the guard followed by a rotate) and only differed in the assembly macros, which now live in the separate pointer_guard-asm.h headers. Remove the redundant per-arch C headers and keep a single implementation in sysdeps/generic/pointer_guard.h, which includes for the assembly definitions. The i386 and x86_64 assembly headers do not depend on the Linux ABI, so move them out of sysdeps/unix/sysv/linux into the generic per-arch directories alongside the other targets. Checked with builds for all supported ABIs. --- sysdeps/arm/pointer_guard.h | 40 ------------ sysdeps/generic/pointer_guard.h | 28 +++++++- .../sysv/linux => }/i386/pointer_guard-asm.h | 0 .../unix/sysv/linux/aarch64/pointer_guard.h | 41 ------------ sysdeps/unix/sysv/linux/alpha/pointer_guard.h | 40 ------------ sysdeps/unix/sysv/linux/csky/pointer_guard.h | 40 ------------ sysdeps/unix/sysv/linux/i386/pointer_guard.h | 48 -------------- .../unix/sysv/linux/loongarch/pointer_guard.h | 41 ------------ .../unix/sysv/linux/powerpc/pointer_guard.h | 38 ----------- sysdeps/unix/sysv/linux/s390/pointer_guard.h | 38 ----------- sysdeps/unix/sysv/linux/sh/pointer_guard.h | 38 ----------- .../sysv/linux/sparc/sparc32/pointer_guard.h | 38 ----------- .../sysv/linux/sparc/sparc64/pointer_guard.h | 38 ----------- .../unix/sysv/linux/x86_64/pointer_guard.h | 64 ------------------- .../linux => }/x86_64/pointer_guard-asm.h | 0 15 files changed, 25 insertions(+), 507 deletions(-) delete mode 100644 sysdeps/arm/pointer_guard.h rename sysdeps/{unix/sysv/linux => }/i386/pointer_guard-asm.h (100%) delete mode 100644 sysdeps/unix/sysv/linux/aarch64/pointer_guard.h delete mode 100644 sysdeps/unix/sysv/linux/alpha/pointer_guard.h delete mode 100644 sysdeps/unix/sysv/linux/csky/pointer_guard.h delete mode 100644 sysdeps/unix/sysv/linux/i386/pointer_guard.h delete mode 100644 sysdeps/unix/sysv/linux/loongarch/pointer_guard.h delete mode 100644 sysdeps/unix/sysv/linux/powerpc/pointer_guard.h delete mode 100644 sysdeps/unix/sysv/linux/s390/pointer_guard.h delete mode 100644 sysdeps/unix/sysv/linux/sh/pointer_guard.h delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h delete mode 100644 sysdeps/unix/sysv/linux/x86_64/pointer_guard.h rename sysdeps/{unix/sysv/linux => }/x86_64/pointer_guard-asm.h (100%) diff --git a/sysdeps/arm/pointer_guard.h b/sysdeps/arm/pointer_guard.h deleted file mode 100644 index 9fa25c708a9..00000000000 --- a/sysdeps/arm/pointer_guard.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Pointer guard implementation. Arm version. - Copyright (C) 2013-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# if (IS_IN (rtld) \ - || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -# else -# include -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -# endif -#endif - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/generic/pointer_guard.h b/sysdeps/generic/pointer_guard.h index 49eb5ca4ba2..aee84c1fa4e 100644 --- a/sysdeps/generic/pointer_guard.h +++ b/sysdeps/generic/pointer_guard.h @@ -1,4 +1,4 @@ -/* Pointer obfuscation implenentation. Generic (no-op) version. +/* Pointer obfuscation implenentation. Generic version. Copyright (C) 2022-2026 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -22,8 +22,30 @@ #include #ifndef __ASSEMBLER__ -# define PTR_MANGLE(x) (void) (x) -# define PTR_DEMANGLE(x) (void) (x) +# include +# include + +# if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_GUARD_VALUE __pointer_chk_guard_local +# else +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_GUARD_VALUE __pointer_chk_guard +# endif + +# define PTR_MANGLE(var) \ + do { \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ + (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \ + 2 * sizeof (uintptr_t) + 1); \ + } while (0) +# define PTR_DEMANGLE(var) \ + do { \ + (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \ + 2 * sizeof (uintptr_t) + 1); \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ + } while (0) #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h b/sysdeps/i386/pointer_guard-asm.h similarity index 100% rename from sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h rename to sysdeps/i386/pointer_guard-asm.h diff --git a/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h b/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h deleted file mode 100644 index 7b7d8b0b714..00000000000 --- a/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Pointer guard implementation. AArch64 version. - Copyright (C) 2014-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# if (IS_IN (rtld) \ - || (!defined SHARED && (IS_IN (libc) \ - || IS_IN (libpthread)))) -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -# else -# include -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -# endif -#endif - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/alpha/pointer_guard.h b/sysdeps/unix/sysv/linux/alpha/pointer_guard.h deleted file mode 100644 index 0741bf7a183..00000000000 --- a/sysdeps/unix/sysv/linux/alpha/pointer_guard.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Pointer guard implementation. Alpha version. - Copyright (C) 2006-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# include -# if (IS_IN (rtld) \ - || (!defined SHARED && (IS_IN (libc) \ - || IS_IN (libpthread)))) -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# else -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (__typeof(var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE(var) -#endif /* ASSEMBLER */ - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/csky/pointer_guard.h b/sysdeps/unix/sysv/linux/csky/pointer_guard.h deleted file mode 100644 index 2aa044bdc42..00000000000 --- a/sysdeps/unix/sysv/linux/csky/pointer_guard.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Pointer obfuscation implenentation. C-SKY version. - Copyright (C) 2022-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# if (IS_IN (rtld) \ - || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) -extern uintptr_t __pointer_chk_guard_local; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -# else -# include -extern uintptr_t __pointer_chk_guard; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -# endif -#endif - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard.h b/sysdeps/unix/sysv/linux/i386/pointer_guard.h deleted file mode 100644 index 7776c282d81..00000000000 --- a/sysdeps/unix/sysv/linux/i386/pointer_guard.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Pointer obfuscation implenentation. i386 version. - Copyright (C) 2005-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# include -# include -# if IS_IN (rtld) || !defined SHARED -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_GUARD_VALUE __pointer_chk_guard_local -# else -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_GUARD_VALUE __pointer_chk_guard -# endif -# define PTR_MANGLE(var) \ - do { \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ - (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \ - 2 * sizeof (uintptr_t) + 1); \ - } while (0) -# define PTR_DEMANGLE(var) \ - do { \ - (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \ - 2 * sizeof (uintptr_t) + 1); \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ - } while (0) -#endif - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h b/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h deleted file mode 100644 index c080bdd0a9d..00000000000 --- a/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Pointer obfuscation implenentation. LoongArch version. - Copyright (C) 2022-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# include -# if (IS_IN (rtld) \ - || (!defined SHARED && (IS_IN (libc) \ - || IS_IN (libpthread)))) -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -# else -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -# endif -#endif - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h deleted file mode 100644 index 51f588ec11c..00000000000 --- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Pointer obfuscation implenentation. PowerPC version. - Copyright (C) 2005-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# include -# if IS_IN (rtld) || !defined SHARED -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# else -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -#endif - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard.h b/sysdeps/unix/sysv/linux/s390/pointer_guard.h deleted file mode 100644 index 403eff63282..00000000000 --- a/sysdeps/unix/sysv/linux/s390/pointer_guard.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Pointer obfuscation implenentation. s390x version. - Copyright (C) 2005-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# include -# if IS_IN (rtld) || !defined SHARED -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_GUARD_VALUE __pointer_chk_guard_local -# else -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_GUARD_VALUE __pointer_chk_guard -# endif -# define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ PTR_GUARD_VALUE) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -#endif - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard.h b/sysdeps/unix/sysv/linux/sh/pointer_guard.h deleted file mode 100644 index 42340faca83..00000000000 --- a/sysdeps/unix/sysv/linux/sh/pointer_guard.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Pointer obfuscation implenentation. SH version. - Copyright (C) 2005-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# include -# if IS_IN (rtld) || !defined SHARED -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# else -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -#endif - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h deleted file mode 100644 index 86d3fbb7d27..00000000000 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Pointer obfuscation implenentation. 32-bit SPARC version. - Copyright (C) 2006-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# include -# if IS_IN (rtld) || !defined SHARED -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# else -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -#endif - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h deleted file mode 100644 index fc0a723905e..00000000000 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Pointer obfuscation implenentation. 64-bit SPARC version. - Copyright (C) 2006-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# include -# if IS_IN (rtld) || !defined SHARED -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# else -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -#endif - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h deleted file mode 100644 index dd3a9752b2a..00000000000 --- a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Pointer obfuscation implenentation. x86-64 version. - Copyright (C) 2005-2026 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 POINTER_GUARD_H -#define POINTER_GUARD_H - -#include - -#ifndef __ASSEMBLER__ -# include -# include - -# if (IS_IN (rtld) \ - || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ - do { \ - (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ __pointer_chk_guard_local); \ - (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \ - 2 * sizeof (uintptr_t) + 1); \ - } while (0) -# define PTR_DEMANGLE(var) \ - do { \ - (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \ - 2 * sizeof (uintptr_t) + 1); \ - (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ __pointer_chk_guard_local); \ - } while (0) -# else -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ - do { \ - (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ __pointer_chk_guard); \ - (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \ - 2 * sizeof (uintptr_t) + 1); \ - } while (0) -# define PTR_DEMANGLE(var) \ - do { \ - (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \ - 2 * sizeof (uintptr_t) + 1); \ - (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ __pointer_chk_guard); \ - } while (0) -# endif -#endif - -#endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h b/sysdeps/x86_64/pointer_guard-asm.h similarity index 100% rename from sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h rename to sysdeps/x86_64/pointer_guard-asm.h From patchwork Wed Jun 3 00:04:37 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 136337 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7C7254BA2E37 for ; Wed, 3 Jun 2026 00:10:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7C7254BA2E37 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=SqH9ttlI X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-yw1-x112c.google.com (mail-yw1-x112c.google.com [IPv6:2607:f8b0:4864:20::112c]) by sourceware.org (Postfix) with ESMTPS id 688604BA2E37 for ; Wed, 3 Jun 2026 00:07:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 688604BA2E37 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 688604BA2E37 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::112c ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445237; cv=none; b=aks2UW8yv9ucMn9MEC+4PzJN3jkkCvUQI2acFzzo81GR1zcM6MWFUVTiXdZGzppiKiJzyrYvMvIqoHvkBOMzKcTqWvR4qkYlcU7BXrUfLeprHVP9CbFqORvJCMtUue17GViSsCBsUYTuTEY5j41dGV2LicL67mevJL+L5enyUWs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445237; c=relaxed/simple; bh=B0rQ2gycIv89wxRMF+geo0EWTREqqQDFP67NqY3G8aM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Msexqm25Fq7xne6k+DRALfgIv5j9euvOVpe4U5IWM19fXMr7rfUewj7yCv/nZ8wUzFbwuF0JxSWkIs2YVwSh6aRk05kHc1a0K1xteEyVWoQhTCWjrIYrEbUrlBuZP4zkWK/ACECGSijJgwiXmfg1LIFC/+W+HBRiIbavZTpbXOA= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=SqH9ttlI DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 688604BA2E37 Received: by mail-yw1-x112c.google.com with SMTP id 00721157ae682-7e8ec43e5f9so18960947b3.0 for ; Tue, 02 Jun 2026 17:07:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1780445237; x=1781050037; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SoKOAUA/QpvKgoNHgKe1BrE29upShYRlO7VneBe9bvA=; b=SqH9ttlICLoKxsJdCBl4cJfBzxPsunfv2P6TTky5XIxmmlsysZ1a3JI+TnptvAxCSn 8lHL6UfUJLO32HRFb9Yo3gaLx6eWbwVB7USg/EGG5BEJ2qxSwIea2qCWkiz6vYzRWGA/ 8/ccA7CrpT5yN0GaYyiGlPWTQC8Tf/bMqDo/UwOiryIZCp3aKhO+bmjh0uF7OuWIqrgL kD8VVC0kaKyXc6im4kSI6dOiLD3AouBxoQuQz0Yjl0bIGBTIjDEuPLBL7lp0WW6NyWsn eq/ZiUBS2qaQRJulWGzDz7aDq6s/Fq0puWbaOpwAHuX0qQ8ULiW2NQU5AO2k+L4KcDrQ MrgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780445237; x=1781050037; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=SoKOAUA/QpvKgoNHgKe1BrE29upShYRlO7VneBe9bvA=; b=Z2iI/Rfpuiylt43hixO5s7b16zUZu4YaNou5M+DJgllucEFR2EeRZip3GzlKnoSJ7X NpsQyGLadGWKqaG4Ktztn0sp+H3HHU5ztP7gS7uu0zBV3wE45vWgIA1qYNBI9ISt4ykf b5omEn7DvYm87E75LQMhQ6TjNdv66KxYswSLq8Y9eZQfwLB9ol+IDvjbGYw4EMOoIrZE 9iILF7lGGnQnbYouvmgG3gDddpgMA5WX8bbFthHhz96/XkThIoYLf+0ayRQ81u6NSckL cJG3yGMxgH+UUJdZFwcpmB4LhSymCM1ErQmM9ucrFCiy3sDGzJqNZC6xaqG21PJ/zvMB QFDg== X-Gm-Message-State: AOJu0YyuQmMdZHWaI5FCM4NbhwYpb5BeVNa9N9ISz5FraneG5kTyeNmH alWAXwMilP76vYLoYodqM6Xs3a9nnFSn2d9FgpdQwwBKEwrL9yP1BMFtfvNydETw4PHYyrRAid9 B5Ww8 X-Gm-Gg: Acq92OFFVTEJ20XbVQLxK+vDmzaoytFxatu5iyPgW3RbxPTc98AH16nh2wzcexq1TcP BLnat704X+YkJLAvm3pa+QyxltgQR7ivZO3cJpcY9v/Zq5uIfxWb4d46ufkSbgJDErqH5akeCdi ga0KA9OOYU0gawKf7K1G+F7N07CKyPN8e0uRXfg5WC1HFYHh7ayRFxx7pj/RA7hoEYXPXf020f9 dkXE/ega318TJb4rD43NXx64+GMVl9OTiXtrAgIZZSNjFYNzdtCLrWZJEeN21cSfiMizj176aN+ jc+rOYni7dF9exRMJ6CK1ImzDoM38YG2J4K4YO6Oxlrr7nBNISBXgKnBzG+D5h0WpsAyGZZmrfS ha8vZoIREUB8Xg3Wbtx+rVJ2nYsVwyQqUvnZzxXlsBspN/FkJTLm9inDHvfmhOZuxdkMsC7WKA5 PREfLQCL42BfTq+SqoRNS0q7v4rRlvFSbI8qHqFJw/Medwk6IuaxsNvCtV X-Received: by 2002:a05:690c:48c6:b0:7e9:4a7:98c6 with SMTP id 00721157ae682-7ea46d2703bmr11362477b3.8.1780445236411; Tue, 02 Jun 2026 17:07:16 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:efc6:8f41:550d:2b14:9278]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7ea23a9946bsm7332207b3.37.2026.06.02.17.07.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jun 2026 17:07:15 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Anderson Nascimento , Carlos O'Donell Subject: [PATCH 6/8] Add the pointer guard rotate to the assembly implementations Date: Tue, 2 Jun 2026 21:04:37 -0300 Message-ID: <20260603000656.3287796-7-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> References: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org The generic C PTR_MANGLE/PTR_DEMANGLE mangle a pointer with an exclusive-or by the guard followed by a rotate left by 2 * sizeof (uintptr_t) + 1 bits (9 on 32-bit, 17 on 64-bit); a demangle rotates right by the same amount before the exclusive-or. The assembly implementations only did the exclusive-or, so align them with the C one. Targets with a rotate instruction (aarch64, arm, loongarch, powerpc, s390, csky) just add it. Those without one (alpha, sparc, sh) synthesize the rotation: alpha and sparc with a shift/shift/or sequence, which needs an extra scratch register added to the PTR_MANGLE/PTR_DEMANGLE macros and their setjmp/__longjmp/____longjmp_chk call sites; sh with single-bit rotates, which needs no scratch. The s390 __longjmp and ____longjmp_chk demangle the return address and stack pointer in C, so update those too. Checked with setjmp, ptrguard and longjmp_chk tests for all supported ABIs that can run under qemu (all but csky). --- sysdeps/alpha/__longjmp.S | 6 +-- sysdeps/alpha/setjmp.S | 8 ++-- sysdeps/arm/pointer_guard-asm.h | 31 ++++++-------- sysdeps/s390/__longjmp.c | 2 + sysdeps/sparc/sparc32/__longjmp.S | 10 ++--- sysdeps/sparc/sparc32/setjmp.S | 6 +-- .../sysv/linux/aarch64/pointer_guard-asm.h | 20 +++++---- .../unix/sysv/linux/alpha/____longjmp_chk.S | 6 +-- .../unix/sysv/linux/alpha/pointer_guard-asm.h | 37 +++++++++------- .../unix/sysv/linux/csky/pointer_guard-asm.h | 42 ++++++++++--------- .../sysv/linux/loongarch/pointer_guard-asm.h | 35 +++++++--------- .../sysv/linux/powerpc/pointer_guard-asm.h | 31 +++++++++++--- .../unix/sysv/linux/s390/____longjmp_chk.c | 4 +- .../unix/sysv/linux/s390/pointer_guard-asm.h | 13 ++++-- .../unix/sysv/linux/sh/pointer_guard-asm.h | 14 +++++-- .../linux/sparc/sparc32/____longjmp_chk.S | 6 +-- .../linux/sparc/sparc32/pointer_guard-asm.h | 21 +++++++--- .../linux/sparc/sparc64/pointer_guard-asm.h | 21 +++++++--- 18 files changed, 184 insertions(+), 129 deletions(-) diff --git a/sysdeps/alpha/__longjmp.S b/sysdeps/alpha/__longjmp.S index 0a18a37789c..f516e9ba614 100644 --- a/sysdeps/alpha/__longjmp.S +++ b/sysdeps/alpha/__longjmp.S @@ -53,9 +53,9 @@ ENTRY(__longjmp) ldt $f8, JB_F8*8(a0) ldt $f9, JB_F9*8(a0) #ifdef PTR_DEMANGLE - PTR_DEMANGLE(ra, t1) - PTR_DEMANGLE2(t0, t1) - PTR_DEMANGLE2(fp, t1) + PTR_DEMANGLE(ra, t1, t2) + PTR_DEMANGLE2(t0, t1, t2) + PTR_DEMANGLE2(fp, t1, t2) #endif cmoveq v0, 1, v0 mov t0, sp diff --git a/sysdeps/alpha/setjmp.S b/sysdeps/alpha/setjmp.S index 8dc3dacab44..bf228991daf 100644 --- a/sysdeps/alpha/setjmp.S +++ b/sysdeps/alpha/setjmp.S @@ -52,22 +52,22 @@ $sigsetjmp_local: stq s4, JB_S4*8(a0) stq s5, JB_S5*8(a0) #ifdef PTR_MANGLE - PTR_MANGLE(t1, ra, t0) + PTR_MANGLE(t1, ra, t0, t2) stq t1, JB_PC*8(a0) #else stq ra, JB_PC*8(a0) #endif #if defined(PTR_MANGLE) && FRAME == 0 - PTR_MANGLE2(t1, sp, t0) + PTR_MANGLE2(t1, sp, t0, t2) #else addq sp, FRAME, t1 # ifdef PTR_MANGLE - PTR_MANGLE2(t1, t1, t0) + PTR_MANGLE2(t1, t1, t0, t2) # endif #endif stq t1, JB_SP*8(a0) #ifdef PTR_MANGLE - PTR_MANGLE2(t1, fp, t0) + PTR_MANGLE2(t1, fp, t0, t2) stq t1, JB_FP*8(a0) #else stq fp, JB_FP*8(a0) diff --git a/sysdeps/arm/pointer_guard-asm.h b/sysdeps/arm/pointer_guard-asm.h index 86a9055b617..e34faa40ca2 100644 --- a/sysdeps/arm/pointer_guard-asm.h +++ b/sysdeps/arm/pointer_guard-asm.h @@ -24,30 +24,23 @@ || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) # define PTR_MANGLE_LOAD(guard, tmp) \ LDR_HIDDEN (guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local), 0) -# define PTR_MANGLE(dst, src, guard, tmp) \ - PTR_MANGLE_LOAD(guard, tmp); \ - PTR_MANGLE2(dst, src, guard) -/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ -# define PTR_MANGLE2(dst, src, guard) \ - eor dst, src, guard -# define PTR_DEMANGLE(dst, src, guard, tmp) \ - PTR_MANGLE (dst, src, guard, tmp) -# define PTR_DEMANGLE2(dst, src, guard) \ - PTR_MANGLE2 (dst, src, guard) # else # define PTR_MANGLE_LOAD(guard, tmp) \ - LDR_GLOBAL (guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard), 0); -# define PTR_MANGLE(dst, src, guard, tmp) \ + LDR_GLOBAL (guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard), 0) +# endif +# define PTR_MANGLE(dst, src, guard, tmp) \ PTR_MANGLE_LOAD(guard, tmp); \ PTR_MANGLE2(dst, src, guard) /* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ -# define PTR_MANGLE2(dst, src, guard) \ - eor dst, src, guard -# define PTR_DEMANGLE(dst, src, guard, tmp) \ - PTR_MANGLE (dst, src, guard, tmp) -# define PTR_DEMANGLE2(dst, src, guard) \ - PTR_MANGLE2 (dst, src, guard) -# endif +# define PTR_MANGLE2(dst, src, guard) \ + eor dst, src, guard; \ + ror dst, dst, #23 +# define PTR_DEMANGLE(dst, src, guard, tmp) \ + PTR_MANGLE_LOAD(guard, tmp); \ + PTR_DEMANGLE2(dst, src, guard) +# define PTR_DEMANGLE2(dst, src, guard) \ + ror dst, src, #9; \ + eor dst, dst, guard #endif #endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/s390/__longjmp.c b/sysdeps/s390/__longjmp.c index 50d67bf42cc..cf59686579a 100644 --- a/sysdeps/s390/__longjmp.c +++ b/sysdeps/s390/__longjmp.c @@ -48,7 +48,9 @@ __longjmp (__jmp_buf env, int val) argument and target address. */ #ifdef PTR_DEMANGLE "lmg %%r4,%%r5,64(%1)\n\t" + "rllg %%r4,%%r4,47\n\t" "xgr %%r4,%2\n\t" + "rllg %%r5,%%r5,47\n\t" "xgr %%r5,%2\n\t" LIBC_PROBE_ASM (longjmp, 8@%1 -4@%0 8@%%r4) #else diff --git a/sysdeps/sparc/sparc32/__longjmp.S b/sysdeps/sparc/sparc32/__longjmp.S index 732a250e4d2..c443011996e 100644 --- a/sysdeps/sparc/sparc32/__longjmp.S +++ b/sysdeps/sparc/sparc32/__longjmp.S @@ -28,7 +28,7 @@ ENTRY(__longjmp) ld ENV(o0,JB_FP), %g3 /* Cache target FP in register %g3. */ #ifdef PTR_DEMANGLE - PTR_DEMANGLE (%g3, %g3, %g4) + PTR_DEMANGLE (%g3, %g3, %g4, %g5) #endif mov %o0, %g1 /* ENV in %g1 */ orcc %o1, %g0, %g2 /* VAL in %g2 */ @@ -66,8 +66,8 @@ LOC(thread): #ifdef PTR_DEMANGLE ld ENV(g1,JB_PC), %g5 /* Set return PC. */ ld ENV(g1,JB_SP), %g1 /* Set saved SP on restore below. */ - PTR_DEMANGLE2 (%i7, %g5, %g4) - PTR_DEMANGLE2 (%fp, %g1, %g4) + PTR_DEMANGLE2 (%i7, %g5, %g4, %g3) + PTR_DEMANGLE2 (%fp, %g1, %g4, %g3) #else ld ENV(g1,JB_PC), %i7 /* Set return PC. */ ld ENV(g1,JB_SP), %fp /* Set saved SP on restore below. */ @@ -78,7 +78,7 @@ LOC(thread): LOC(found): /* We have unwound register windows so %fp matches the target. */ #ifdef PTR_DEMANGLE - PTR_DEMANGLE2 (%sp, %o0, %g4) + PTR_DEMANGLE2 (%sp, %o0, %g4, %g3) #else mov %o0, %sp /* OK, install new SP. */ #endif @@ -86,7 +86,7 @@ LOC(found): LOC(sp_ok): ld ENV(g1,JB_PC), %o0 /* Extract target return PC. */ #ifdef PTR_DEMANGLE - PTR_DEMANGLE2 (%o0, %o0, %g4) + PTR_DEMANGLE2 (%o0, %o0, %g4, %g3) #endif jmp %o0 + 8 /* Return there. */ mov %g2, %o0 /* Delay slot: set return value. */ diff --git a/sysdeps/sparc/sparc32/setjmp.S b/sysdeps/sparc/sparc32/setjmp.S index 5f2aec113ac..e389c5077e5 100644 --- a/sysdeps/sparc/sparc32/setjmp.S +++ b/sysdeps/sparc/sparc32/setjmp.S @@ -38,9 +38,9 @@ ENTRY (__sigsetjmp) ta ST_FLUSH_WINDOWS #ifdef PTR_MANGLE - PTR_MANGLE (%g1, %o7, %g4) - PTR_MANGLE2 (%g2, %sp, %g4) - PTR_MANGLE2 (%g3, %fp, %g4) + PTR_MANGLE (%g1, %o7, %g4, %g5) + PTR_MANGLE2 (%g2, %sp, %g4, %g5) + PTR_MANGLE2 (%g3, %fp, %g4, %g5) st %g1, [%o0 + (JB_PC * 4)] st %g2, [%o0 + (JB_SP * 4)] st %g3, [%o0 + (JB_FP * 4)] diff --git a/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h index ed483a806a6..0fd26973412 100644 --- a/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h +++ b/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h @@ -23,19 +23,23 @@ # if (IS_IN (rtld) \ || (!defined SHARED && (IS_IN (libc) \ || IS_IN (libpthread)))) -# define PTR_MANGLE(dst, src, tmp) \ +# define PTR_GUARD_LOAD(tmp) \ adrp tmp, C_SYMBOL_NAME(__pointer_chk_guard_local); \ - ldr tmp, [tmp, :lo12:C_SYMBOL_NAME(__pointer_chk_guard_local)]; \ - eor dst, src, tmp -# define PTR_DEMANGLE(dst, src, tmp) PTR_MANGLE (dst, src, tmp) + ldr tmp, [tmp, :lo12:C_SYMBOL_NAME(__pointer_chk_guard_local)] # else -# define PTR_MANGLE(dst, src, tmp) \ +# define PTR_GUARD_LOAD(tmp) \ adrp tmp, :got:C_SYMBOL_NAME(__pointer_chk_guard); \ ldr tmp, [tmp, :got_lo12:C_SYMBOL_NAME(__pointer_chk_guard)]; \ - ldr tmp, [tmp]; \ - eor dst, src, tmp; -# define PTR_DEMANGLE(dst, src, tmp) PTR_MANGLE (dst, src, tmp) + ldr tmp, [tmp] # endif +# define PTR_MANGLE(dst, src, tmp) \ + PTR_GUARD_LOAD (tmp); \ + eor dst, src, tmp; \ + ror dst, dst, #(64 - 17) +# define PTR_DEMANGLE(dst, src, tmp) \ + PTR_GUARD_LOAD (tmp); \ + ror dst, src, #17; \ + eor dst, dst, tmp #endif #endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/alpha/____longjmp_chk.S b/sysdeps/unix/sysv/linux/alpha/____longjmp_chk.S index 6661db76c9b..135eb10faa0 100644 --- a/sysdeps/unix/sysv/linux/alpha/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/alpha/____longjmp_chk.S @@ -54,9 +54,9 @@ ____longjmp_chk: cmoveq s1, 1, s1 #ifdef PTR_DEMANGLE - PTR_DEMANGLE(s2, t1) - PTR_DEMANGLE2(s3, t1) - PTR_DEMANGLE2(fp, t1) + PTR_DEMANGLE(s2, t1, t2) + PTR_DEMANGLE2(s3, t1, t2) + PTR_DEMANGLE2(fp, t1, t2) #endif /* ??? While this is a proper test for detecting a longjmp to an invalid frame within any given stack, the main thread stack is diff --git a/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h index 15f9e6cacef..3ca56dd7aa4 100644 --- a/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h +++ b/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h @@ -21,25 +21,32 @@ #ifdef __ASSEMBLER__ # if IS_IN (rtld) -# define PTR_MANGLE(dst, src, tmp) \ +# define PTR_GUARD_LOAD(tmp) \ ldah tmp, __pointer_chk_guard_local($29) !gprelhigh; \ - ldq tmp, __pointer_chk_guard_local(tmp) !gprellow; \ - xor src, tmp, dst -# define PTR_MANGLE2(dst, src, tmp) \ - xor src, tmp, dst + ldq tmp, __pointer_chk_guard_local(tmp) !gprellow # elif defined SHARED -# define PTR_MANGLE(dst, src, tmp) \ - ldq tmp, __pointer_chk_guard; \ - xor src, tmp, dst +# define PTR_GUARD_LOAD(tmp) \ + ldq tmp, __pointer_chk_guard # else -# define PTR_MANGLE(dst, src, tmp) \ - ldq tmp, __pointer_chk_guard_local; \ - xor src, tmp, dst +# define PTR_GUARD_LOAD(tmp) \ + ldq tmp, __pointer_chk_guard_local # endif -# define PTR_MANGLE2(dst, src, tmp) \ - xor src, tmp, dst -# define PTR_DEMANGLE(dst, tmp) PTR_MANGLE(dst, dst, tmp) -# define PTR_DEMANGLE2(dst, tmp) PTR_MANGLE2(dst, dst, tmp) +# define PTR_MANGLE(dst, src, tmp, tmp2) \ + PTR_GUARD_LOAD (tmp); \ + PTR_MANGLE2 (dst, src, tmp, tmp2) +# define PTR_MANGLE2(dst, src, tmp, tmp2) \ + xor src, tmp, dst; \ + sll dst, 17, tmp2; \ + srl dst, 47, dst; \ + bis dst, tmp2, dst +# define PTR_DEMANGLE(dst, tmp, tmp2) \ + PTR_GUARD_LOAD (tmp); \ + PTR_DEMANGLE2 (dst, tmp, tmp2) +# define PTR_DEMANGLE2(dst, tmp, tmp2) \ + sll dst, 47, tmp2; \ + srl dst, 17, dst; \ + bis dst, tmp2, dst; \ + xor dst, tmp, dst #endif #endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h index 8eb6d2c1d42..074251cbdf8 100644 --- a/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h +++ b/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h @@ -22,34 +22,36 @@ #ifdef __ASSEMBLER__ # if (IS_IN (rtld) \ || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) -# define PTR_MANGLE(dst, src, guard) \ +# define PTR_MANGLE_LOAD(guard) \ grs t0, 1f; \ 1: \ lrw guard, 1b@GOTPC; \ addu t0, guard; \ lrw guard, __pointer_chk_guard_local@GOT; \ ldr.w guard, (t0, guard << 0); \ - ldw guard, (guard, 0); \ - xor dst, src, guard; -# define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard) -# define PTR_MANGLE2(dst, src, guard) \ - xor dst, src, guard -# define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard) + ldw guard, (guard, 0); # else -# define PTR_MANGLE(dst, src, guard) \ - grs t0, 1f; \ -1: \ - lrw guard, 1b@GOTPC; \ - addu t0, guard; \ - lrw guard, __pointer_chk_guard@GOT; \ - ldr.w guard, (t0, guard << 0); \ - ldw guard, (guard, 0); \ - xor dst, src, guard; -# define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard) -# define PTR_MANGLE2(dst, src, guard) \ - xor dst, src, guard -# define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard) +# define PTR_MANGLE_LOAD(guard) \ + grs t0, 1f; \ +1: \ + lrw guard, 1b@GOTPC; \ + addu t0, guard; \ + lrw guard, __pointer_chk_guard@GOT; \ + ldr.w guard, (t0, guard << 0); \ + ldw guard, (guard, 0); # endif +# define PTR_MANGLE(dst, src, guard) \ + PTR_MANGLE_LOAD (guard); \ + PTR_MANGLE2 (dst, src, guard) +# define PTR_MANGLE2(dst, src, guard) \ + xor dst, src, guard; \ + rotli dst, dst, 9 +# define PTR_DEMANGLE(dst, src, guard) \ + PTR_MANGLE_LOAD (guard); \ + PTR_DEMANGLE2 (dst, src, guard) +# define PTR_DEMANGLE2(dst, src, guard) \ + rotli dst, src, 23; \ + xor dst, dst, guard #endif #endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h index ac55dd8c95c..75498545cb9 100644 --- a/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h +++ b/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h @@ -23,30 +23,25 @@ # if (IS_IN (rtld) \ || (!defined SHARED && (IS_IN (libc) \ || IS_IN (libpthread)))) -# define PTR_MANGLE(dst, src, guard) \ - LOAD_LOCAL (guard, __pointer_chk_guard_local); \ - PTR_MANGLE2 (dst, src, guard); -# define PTR_DEMANGLE(dst, src, guard) \ - LOAD_LOCAL (guard, __pointer_chk_guard_local); \ - PTR_DEMANGLE2 (dst, src, guard); -/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ -# define PTR_MANGLE2(dst, src, guard) \ - xor dst, src, guard; -# define PTR_DEMANGLE2(dst, src, guard) \ - PTR_MANGLE2 (dst, src, guard); +# define PTR_MANGLE_LOAD(guard) \ + LOAD_LOCAL (guard, __pointer_chk_guard_local); # else -# define PTR_MANGLE(dst, src, guard) \ - LOAD_GLOBAL (guard, __pointer_chk_guard); \ +# define PTR_MANGLE_LOAD(guard) \ + LOAD_GLOBAL (guard, __pointer_chk_guard); +# endif +# define PTR_MANGLE(dst, src, guard) \ + PTR_MANGLE_LOAD (guard); \ PTR_MANGLE2 (dst, src, guard); -# define PTR_DEMANGLE(dst, src, guard) \ - LOAD_GLOBAL (guard, __pointer_chk_guard); \ +# define PTR_DEMANGLE(dst, src, guard) \ + PTR_MANGLE_LOAD (guard); \ PTR_DEMANGLE2 (dst, src, guard); /* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ -# define PTR_MANGLE2(dst, src, guard) \ - xor dst, src, guard; -# define PTR_DEMANGLE2(dst, src, guard) \ - PTR_MANGLE2 (dst, src, guard); -# endif +# define PTR_MANGLE2(dst, src, guard) \ + xor dst, src, guard; \ + rotri.d dst, dst, 47; +# define PTR_DEMANGLE2(dst, src, guard) \ + rotri.d dst, src, 17; \ + xor dst, dst, guard; #endif #endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h index ca4278cc00a..962ad10e596 100644 --- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h +++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h @@ -50,17 +50,36 @@ lwz tmpreg,PTR_GUARD_SYM@l(tmpreg) # endif +# if defined(__PPC64__) || defined(__powerpc64__) +# define PTR_ROT_MANGLE(dst, src) rotldi dst,src,17 +# define PTR_ROT_DEMANGLE(dst, src) rotldi dst,src,47 +# else +# define PTR_ROT_MANGLE(dst, src) rotlwi dst,src,9 +# define PTR_ROT_DEMANGLE(dst, src) rotlwi dst,src,23 +# endif + # define PTR_MANGLE(reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ - xor reg,tmpreg,reg + xor reg,tmpreg,reg; \ + PTR_ROT_MANGLE (reg, reg) # define PTR_MANGLE2(reg, tmpreg) \ - xor reg,tmpreg,reg + xor reg,tmpreg,reg; \ + PTR_ROT_MANGLE (reg, reg) # define PTR_MANGLE3(destreg, reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ - xor destreg,tmpreg,reg -# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) -# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) -# define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg) + xor destreg,tmpreg,reg; \ + PTR_ROT_MANGLE (destreg, destreg) +# define PTR_DEMANGLE(reg, tmpreg) \ + PTR_GUARD_LOAD (tmpreg); \ + PTR_ROT_DEMANGLE (reg, reg); \ + xor reg,tmpreg,reg +# define PTR_DEMANGLE2(reg, tmpreg) \ + PTR_ROT_DEMANGLE (reg, reg); \ + xor reg,tmpreg,reg +# define PTR_DEMANGLE3(destreg, reg, tmpreg) \ + PTR_GUARD_LOAD (tmpreg); \ + PTR_ROT_DEMANGLE (destreg, reg); \ + xor destreg,tmpreg,destreg #endif #endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/s390/____longjmp_chk.c b/sysdeps/unix/sysv/linux/s390/____longjmp_chk.c index 4186114844d..7ee7bf71cff 100644 --- a/sysdeps/unix/sysv/linux/s390/____longjmp_chk.c +++ b/sysdeps/unix/sysv/linux/s390/____longjmp_chk.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,8 @@ uintptr_t cur_sp; \ uintptr_t new_sp = env->__gregs[9]; \ __asm__ ("lgr %0, %%r15" : "=r" (cur_sp)); \ - new_sp ^= guard; \ + new_sp = stdc_rotate_right (new_sp, 2 * sizeof (uintptr_t) + 1) \ + ^ guard; \ if (new_sp < cur_sp) \ { \ stack_t oss; \ diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h index 71cc0465d13..44c9a2a156b 100644 --- a/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h +++ b/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h @@ -32,11 +32,18 @@ # endif # define PTR_MANGLE(reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ - xgr reg,tmpreg + xgr reg,tmpreg; \ + rllg reg,reg,17 # define PTR_MANGLE2(reg, tmpreg) \ + xgr reg,tmpreg; \ + rllg reg,reg,17 +# define PTR_DEMANGLE(reg, tmpreg) \ + PTR_GUARD_LOAD (tmpreg); \ + rllg reg,reg,47; \ + xgr reg,tmpreg +# define PTR_DEMANGLE2(reg, tmpreg) \ + rllg reg,reg,47; \ xgr reg,tmpreg -# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) -# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) #endif #endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h index 64e6f6153e8..f6002efdead 100644 --- a/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h +++ b/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h @@ -55,10 +55,16 @@ .Lptrg_end: # endif # define PTR_MANGLE(reg, tmp) \ - PTR_GUARD_LOAD (tmp); xor tmp,reg -# define PTR_MANGLE2(reg, tmp) xor tmp,reg -# define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp) -# define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp) + PTR_GUARD_LOAD (tmp); PTR_MANGLE2 (reg, tmp) +# define PTR_MANGLE2(reg, tmp) \ + xor tmp,reg; \ + rotl reg; rotl reg; rotl reg; rotl reg; rotl reg; \ + rotl reg; rotl reg; rotl reg; rotl reg +# define PTR_DEMANGLE(reg, tmp) PTR_GUARD_LOAD (tmp); PTR_DEMANGLE2 (reg, tmp) +# define PTR_DEMANGLE2(reg, tmp) \ + rotr reg; rotr reg; rotr reg; rotr reg; rotr reg; \ + rotr reg; rotr reg; rotr reg; rotr reg; \ + xor tmp,reg #endif #endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S b/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S index b0c6160bd28..07baa0c9ed2 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S @@ -32,7 +32,7 @@ longjmp_msg: ENTRY (____longjmp_chk) ld ENV(o0,JB_SP), %g5 #ifdef PTR_DEMANGLE - PTR_DEMANGLE (%g5, %g5, %g4) + PTR_DEMANGLE (%g5, %g5, %g4, %g3) #endif cmp %sp, %g5 @@ -82,7 +82,7 @@ ENTRY (____longjmp_chk) .Lok_norestore: ld ENV(o0,JB_FP), %g3 /* Cache target FP in register %g3. */ #ifdef PTR_DEMANGLE - PTR_DEMANGLE2 (%g3, %g3, %g4) + PTR_DEMANGLE2 (%g3, %g3, %g4, %g1) #endif mov %o0, %g1 /* ENV in %g1 */ @@ -103,7 +103,7 @@ ENTRY (____longjmp_chk) ta ST_FLUSH_WINDOWS #ifdef PTR_DEMANGLE ld ENV(g1,JB_PC), %g1 /* Set return PC. */ - PTR_DEMANGLE2 (%i7, %g1, %g4) + PTR_DEMANGLE2 (%i7, %g1, %g4, %g3) #else ld ENV(g1,JB_PC), %i7 /* Set return PC. */ #endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h index e1e42f8087a..aa2b7609c92 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h @@ -39,13 +39,22 @@ sethi %hi(PTR_GUARD_SYM), tmpreg; \ ld [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg # endif -# define PTR_MANGLE(dreg, reg, tmpreg) \ +# define PTR_MANGLE(dreg, reg, tmpreg, tmp2) \ PTR_GUARD_LOAD (tmpreg); \ - xor reg, tmpreg, dreg -# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) -# define PTR_MANGLE2(dreg, reg, tmpreg) \ - xor reg, tmpreg, dreg -# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) + PTR_MANGLE2 (dreg, reg, tmpreg, tmp2) +# define PTR_MANGLE2(dreg, reg, tmpreg, tmp2) \ + xor reg, tmpreg, dreg; \ + sll dreg, 9, tmp2; \ + srl dreg, 23, dreg; \ + or dreg, tmp2, dreg +# define PTR_DEMANGLE(dreg, reg, tmpreg, tmp2) \ + PTR_GUARD_LOAD (tmpreg); \ + PTR_DEMANGLE2 (dreg, reg, tmpreg, tmp2) +# define PTR_DEMANGLE2(dreg, reg, tmpreg, tmp2) \ + srl reg, 9, tmp2; \ + sll reg, 23, dreg; \ + or dreg, tmp2, dreg; \ + xor dreg, tmpreg, dreg #endif #endif /* POINTER_GUARD_ASM_H */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h index f378c88e58c..ef5b38f541b 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h @@ -39,13 +39,22 @@ sethi %hi(PTR_GUARD_SYM), tmpreg; \ ldx [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg # endif -# define PTR_MANGLE(dreg, reg, tmpreg) \ +# define PTR_MANGLE(dreg, reg, tmpreg, tmp2) \ PTR_GUARD_LOAD (tmpreg); \ - xor reg, tmpreg, dreg -# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) -# define PTR_MANGLE2(dreg, reg, tmpreg) \ - xor reg, tmpreg, dreg -# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) + PTR_MANGLE2 (dreg, reg, tmpreg, tmp2) +# define PTR_MANGLE2(dreg, reg, tmpreg, tmp2) \ + xor reg, tmpreg, dreg; \ + sllx dreg, 17, tmp2; \ + srlx dreg, 47, dreg; \ + or dreg, tmp2, dreg +# define PTR_DEMANGLE(dreg, reg, tmpreg, tmp2) \ + PTR_GUARD_LOAD (tmpreg); \ + PTR_DEMANGLE2 (dreg, reg, tmpreg, tmp2) +# define PTR_DEMANGLE2(dreg, reg, tmpreg, tmp2) \ + srlx reg, 17, tmp2; \ + sllx reg, 47, dreg; \ + or dreg, tmp2, dreg; \ + xor dreg, tmpreg, dreg #endif #endif /* POINTER_GUARD_ASM_H */ From patchwork Wed Jun 3 00:04:38 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 136341 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 04D1D4BA2E2E for ; Wed, 3 Jun 2026 00:13:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 04D1D4BA2E2E Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=IJljqe+E X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-yw1-x1130.google.com (mail-yw1-x1130.google.com [IPv6:2607:f8b0:4864:20::1130]) by sourceware.org (Postfix) with ESMTPS id 1EC504BA2E3A for ; Wed, 3 Jun 2026 00:07:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1EC504BA2E3A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1EC504BA2E3A Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1130 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445239; cv=none; b=oStqGBlgPpDpbfQSGiGlc7oIL7naySNNIW/pYSRwQPIH0DDjPoPVnCfDxT9/8AF6ATYSuPjA2/KTgKTC6fi9sbY9nzBvj4eVdOBKZwWCJC8KCBcQhnQpeYjDghWXTmVPWfFfQLcdk36P7OnsI3GXHaw3kBBdWGLZ8UVMmYNuczA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445239; c=relaxed/simple; bh=3uq8Yy2nIU+IMrW+c0BAUf3R0z/PAj8Q9cr6mvhqO/U=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=JT+TptAPc+gbyc9OS/vtsRmIKmNKXTVChgx6wB1x1G6w8JwCB6SqIWw/U2e6ucxKz+wlmU02fbzZcHgsJmhNVMvx4ck3NOBMkim+fYWEKGaS1Zq45Bap1Og2JymBk1gK0fpKvB/lEKQzLK09pVPU9povfnpoSribhIfSlzkvbLQ= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=IJljqe+E DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1EC504BA2E3A Received: by mail-yw1-x1130.google.com with SMTP id 00721157ae682-7ea16f090b4so8316477b3.2 for ; Tue, 02 Jun 2026 17:07:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1780445238; x=1781050038; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RuPEPlWBm7V/cIZFKT1Bc0CuGf5WDZASciM4hscENsc=; b=IJljqe+EOznfKSDUeZ+FggNDwEKAwExfeECjmW3mdW6QfiTpnRUJjJzX/r//zR8mja n27LghoHYgwNWwEJxUUCyIXKWRHq0+NtD8UMC10W1yfmoSusAzrNaNNsdNi4WVkFKDdT runOhLXu1Dr7SCNQA+cs6rgTKvYXn7iQbKRWOUnRoSUlgRYM86BPHKpTJGvWNdMxICcg 0BA9IQgEahbhU/rt6nCLQWVTN4UzWsMloq6LOiXV2nOrGWibhhx+FAPQRO3SSvim1d1D Ex7pRkLOkgbU1ANKs4WCQkXddx1H5DA5hSzlc/h1xagzfU7z7rUHAz5lnFiCv8VoJcQS 0Baw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780445238; x=1781050038; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=RuPEPlWBm7V/cIZFKT1Bc0CuGf5WDZASciM4hscENsc=; b=pAJkIgkWqInKqlwlrh8lLNFJ+Uu0JOCsIaGxJcIKp1/I0bR2glGUoJ4U4EnI397CPX kRADsnPDQNohVeYi3st+Kq1V8I2O3Y6WmsHXRyD8ohvDWlXvtTVrZNjz/lHBcc4Bpbkk X6ngifCDpM7Nuru5zvgdVBrEJNnmSr4qi840Ix6Yeji2zqRuvC4ohkzN/1DcIZT///ky SfWhhXkQFeZWF9b1Y9/WHUkkKa9WCSUE7P7RDSpb9EwbXPDoJfRt59/qmCrAtcb+QLSC BbP2tHxncES4GCQBvc1GVc0qq0fDIyoXtsgxTiq30phYRMlv/RtjMVT/oBq27gts03W7 Egqw== X-Gm-Message-State: AOJu0YyBYU/0THJcPd7oHx+cbaR/peAVyqBXiWurCNHVHivq8Mh2R4Hh 3TI0YFQJYjSQkSy56Kok8oiOpo92bK/0ZG2TialXbODuP3LchfbwPKj3X7z9pYhZ41t1o1kJ6Pq aZhGd X-Gm-Gg: Acq92OH+P/O2M2lVWJafZr9O7FX/uSlqV5KLcNW4Y6+ufbsWSn54WQCuA9KKu6YCAz9 aylLJ9EtOKRJyRB8DQKGadYSw1YBzKBA8vKbxfiZn8jX7LeheIRtMDaw3byqM0RrQ7gTu50hHU7 WRnId3DWdeExrrn1B4CmE73suY165A0oxxR7kZ7Z0kM3oEa/0Ljliyy5qowmBjaoMmJacyTtBZs 2KeaugK/egSUlQrq/rwL9O96ulRo60WTQUCqelatadnHrU0v2YmDyWpWhP7EpZmyQeUX8iJM0Sp p7hkdn+DKOox8EBf8PhIKTduBvgp5cBsLLTBTEoaySjHBRrrJNA+d8qJVJwYDLq8pnUKWO0Fdmn /DpuJp4zOiObYInpw8sfWXF03waHCkNzld+YtYiEa0gG3PMQlLWQnX0m9AeWp5rEap8rjLBJ11Y 150JzyboPhyc6fzwayuEFOdnw6Z4YxUVVI1kEggxQhwpg0C1Iz/1alo2sV X-Received: by 2002:a05:690c:3587:b0:79b:d56a:a7c2 with SMTP id 00721157ae682-7ea4b9d7d15mr11752377b3.48.1780445238374; Tue, 02 Jun 2026 17:07:18 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:efc6:8f41:550d:2b14:9278]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7ea23a9946bsm7332207b3.37.2026.06.02.17.07.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jun 2026 17:07:17 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Anderson Nascimento , Carlos O'Donell Subject: [PATCH 7/8] Consolidate dl-osinfo.h into the generic implementation Date: Tue, 2 Jun 2026 21:04:38 -0300 Message-ID: <20260603000656.3287796-8-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> References: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org The generic and the Linux _dl_setup_stack_chk_guard and _dl_setup_pointer_guard are identical when the kernel provides the AT_RANDOM auxiliary vector, which is always the case on the supported Linux kernels; the generic version only adds a fallback for a missing AT_RANDOM. Remove the Linux-specific dl-osinfo.h and use the generic one for all targets. The removed header pulled in , which is what transitively declared __libc_enable_secure for dl-parse_auxv.h; include there directly so it no longer relies on that. Include in the generic header so it is self-contained. --- sysdeps/generic/dl-osinfo.h | 1 + sysdeps/unix/sysv/linux/dl-osinfo.h | 54 ------------------------- sysdeps/unix/sysv/linux/dl-parse_auxv.h | 1 + 3 files changed, 2 insertions(+), 54 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/dl-osinfo.h diff --git a/sysdeps/generic/dl-osinfo.h b/sysdeps/generic/dl-osinfo.h index de46926abc9..5bb55cfe8a1 100644 --- a/sysdeps/generic/dl-osinfo.h +++ b/sysdeps/generic/dl-osinfo.h @@ -18,6 +18,7 @@ #include #include +#include static inline uintptr_t __attribute__ ((always_inline)) _dl_setup_stack_chk_guard (void *dl_random) diff --git a/sysdeps/unix/sysv/linux/dl-osinfo.h b/sysdeps/unix/sysv/linux/dl-osinfo.h deleted file mode 100644 index 5ff92b76f96..00000000000 --- a/sysdeps/unix/sysv/linux/dl-osinfo.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Operating system specific code for generic dynamic loader functions. Linux. - Copyright (C) 2000-2026 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 - -static inline uintptr_t __attribute__ ((always_inline)) -_dl_setup_stack_chk_guard (void *dl_random) -{ - union - { - uintptr_t num; - unsigned char bytes[sizeof (uintptr_t)]; - } ret; - - /* We need in the moment only 8 bytes on 32-bit platforms and 16 - bytes on 64-bit platforms. Therefore we can use the data - directly and not use the kernel-provided data to seed a PRNG. */ - memcpy (ret.bytes, dl_random, sizeof (ret)); -#if BYTE_ORDER == LITTLE_ENDIAN - ret.num &= ~(uintptr_t) 0xff; -#elif BYTE_ORDER == BIG_ENDIAN - ret.num &= ~((uintptr_t) 0xff << (8 * (sizeof (ret) - 1))); -#else -# error "BYTE_ORDER unknown" -#endif - return ret.num; -} - -static inline uintptr_t __attribute__ ((always_inline)) -_dl_setup_pointer_guard (void *dl_random, uintptr_t stack_chk_guard) -{ - uintptr_t ret; - memcpy (&ret, (char *) dl_random + sizeof (ret), sizeof (ret)); - return ret; -} diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h index 69b6905f7ce..d1cd4373239 100644 --- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h +++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h @@ -22,6 +22,7 @@ #include #include #include +#include /* For __libc_enable_secure. */ typedef ElfW(Addr) dl_parse_auxv_t[AT_MINSIGSTKSZ + 1]; From patchwork Wed Jun 3 00:04:39 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 136339 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A0CDD4BA2E25 for ; Wed, 3 Jun 2026 00:12:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A0CDD4BA2E25 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=mQA508re X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-yw1-x112a.google.com (mail-yw1-x112a.google.com [IPv6:2607:f8b0:4864:20::112a]) by sourceware.org (Postfix) with ESMTPS id C966C4BA2E19 for ; Wed, 3 Jun 2026 00:07:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C966C4BA2E19 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C966C4BA2E19 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::112a ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445241; cv=none; b=BTWlxKcq2y6/sEsl/PAxzwLk8Ta4d/oiCrEqt8q4h+uhS+SaAZhnmdq+jYwdyY25NtR8sfj6S7IUmu1RU6+HKL/3QquFS93p9N9kJA7lL+ar8BFfHzvEXqygJ8Eau/GF6RbfY/i4hnBaPZBm1jjh12fZiGiWxxgE2qbA0dbqkFw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780445241; c=relaxed/simple; bh=TpW7tuJE6ZWuPARTULYjXh3vVETLIm/Nt2o3V7HGgBU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=kOFUbZafwj9kQhlJuZUIGdP6qEd7e7fywEV3Gk/dam6Rqgstrh6meIurbPKpi+Ta2qU2KD0CQeduIDbHlWOJA/KpOcbTpEvUD+79uaLf7pxAUAdfKMUEIL2PtO5UdcmzLckoIsDkIFm8R7FPWOkYbt5knkF37t02WlNszqEojwU= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=mQA508re DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C966C4BA2E19 Received: by mail-yw1-x112a.google.com with SMTP id 00721157ae682-7dd3f176f84so65485137b3.0 for ; Tue, 02 Jun 2026 17:07:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1780445241; x=1781050041; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Kq6EziGEPYPbwEmXTDk/b9yrfdFTOL00u8e9slDh8pQ=; b=mQA508rex0XqBlgEW10YKw1nLaw3LfUahpYY8MCC/Gtp7nCMXJH3i4ikLvNA8D7d3o XdbxOZA836BZZj2X2fVLxdft215aiF20RpjODRzGtifo+mLQVmNA4L4y8FRIVUkiJlXB FwneNkaCPtiHBg/5XdswdHNpqBvqYzAEog2Utdy8CVQN5g/44Rq0k8jJKCEtABG1lSjA zkyvB4VpyZMzIZxX0Rg24zMHShwmXDHSugx6CtSZWEj20OBJM08BRqf/N8xDGULsfPuh jzis7EqB+1olGA/GsuTAgp7RIjhsYoCaVA/j88Z9CX+fbAcJcERNlfSuaagfSXiNEhb/ rn9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780445241; x=1781050041; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Kq6EziGEPYPbwEmXTDk/b9yrfdFTOL00u8e9slDh8pQ=; b=T/2hxQ90xSYaepCyRTj1ry7GnXkuIamI+gByp3YgWSafxLomSIA2KypGIEtOkouhCP rL0ztpySCddW+loEgFEyJEdo+3iVLrs9mC4bwQ9tW7Xr42dbmxHxk66Uv9Bxlwa/jeeZ gzsPDzXMWVN1S4q0+fLv8ZPACbJeTwJ5mmrxrknodalql129bdUQ8tuOsoM3sRNnG0/h 6cR/oh4zwdXoU5beekRiJKd7KPLpy9kR5oXdmUm76evzFf63t/AOAvg4U6jo+phB9H5r 2A5b+xLKcWL6ETKf6M36pfYElN4P8HUkl0d/f+jv0yEBTqjKzDZwztGVWDxmvyKXhUxj /DsA== X-Gm-Message-State: AOJu0YzuK3u0TTmUa5P5udSSOm4/Z68FWzwxI/b+VwJczt/q966kgyMu G/Z0bf5rO+bH9UwvRutFYf+xLfJqRTMRroQTtZSvPM1Cu30dRwc1tgiw+UJFzFeGe1JSnQ4YP0c z0yxD X-Gm-Gg: Acq92OFNB2ay4ov8WNT5thdXTbIQKkVheXTBOT4VsMEMlmiKQdsLNceKOGmNTwTHMG5 ACda0l14lWVMEVsP7JKmUv1nszz80RjQvg4Bd55tB0YIZeGhZW142CRjtYLrBE+/YJFSjblH3QF opRncLh3E2LH7S5aeilb69HfanAdKmVQmSUY4f5OLnfyFDgFLDYdG06nr1QW8NGt/ov9VaIu07J oAvM45AaLhMIpfolhu05oVSFCTeVUpJ8D46eJj3Onfaml0rnmwdysdlJ1kdO6yApqgfMD+DQNVQ UYjVcjKpl4fYFQBHbZ/H1B07ltzCsRjSMQ1s4frs9tVqIETEphyaJ8hpHQy/2QFpCBLeytkU9Rp v/Oa5ASi3MhiWcuyHitff85p/4BOvu5jr3akCcibt3Oc5ijGs/+1D+VVF+MrBckTVNVe1fGxbnU AHIpynI/HDRjWFlThQUv6VvqKftfkDhBOUU2KQYuKaMRMdhg== X-Received: by 2002:a05:690c:610b:b0:7dc:fc4c:58bd with SMTP id 00721157ae682-7ea49e688bamr11487767b3.35.1780445240914; Tue, 02 Jun 2026 17:07:20 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:efc6:8f41:550d:2b14:9278]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7ea23a9946bsm7332207b3.37.2026.06.02.17.07.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jun 2026 17:07:19 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Anderson Nascimento , Carlos O'Donell Subject: [PATCH 8/8] elf: Scrub and reseed the AT_RANDOM bytes after deriving the guards (BZ 34197) Date: Tue, 2 Jun 2026 21:04:39 -0300 Message-ID: <20260603000656.3287796-9-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> References: <20260603000656.3287796-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Once the pointer and stack guards have been derived from AT_RANDOM, scrub the bytes and refill them with new random data unrelated to the guards. On Linux, it uses getrandom syscall (as for tcache_key_initialize), and fallback to zero the memory if the syscall is not avaiable. This keeps AT_RANDOM useful to applications while ensuring those bytes no longer reveal the guards. The work is done by _dl_reseed_random, called once the guards are in place and before any ELF constructor can observe AT_RANDOM: in security_init for the dynamic loader and in __libc_start_main for statically linked programs. Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. --- csu/libc-start.c | 4 ++ elf/Makefile | 5 ++ elf/rtld.c | 6 +- elf/tst-atrandom-scrub-static.c | 1 + elf/tst-atrandom-scrub.c | 74 ++++++++++++++++++++++ sysdeps/generic/dl-reseed-random.h | 34 ++++++++++ sysdeps/unix/sysv/linux/dl-reseed-random.h | 43 +++++++++++++ 7 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 elf/tst-atrandom-scrub-static.c create mode 100644 elf/tst-atrandom-scrub.c create mode 100644 sysdeps/generic/dl-reseed-random.h create mode 100644 sysdeps/unix/sysv/linux/dl-reseed-random.h diff --git a/csu/libc-start.c b/csu/libc-start.c index 03d770ef157..66ef4e3ffc4 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -44,6 +44,8 @@ extern void __libc_init_first (int argc, char **argv, char **envp); #include #ifndef SHARED # include +# include +# include # ifndef THREAD_SET_STACK_GUARD /* Only exported for architectures that don't store the stack guard canary in thread local area. */ @@ -300,6 +302,8 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), __pointer_chk_guard_local = pointer_chk_guard; # endif + _dl_reseed_random (&_dl_random); + /* Now that the TCB, canary, and pointer guard are in place, run the deferred IFUNC relocations. For non-PIE static binaries this is ARCH_SETUP_IREL (apply_irel); for static-pie it is the IRELATIVE diff --git a/elf/Makefile b/elf/Makefile index a940b3045e5..75e86dadc4f 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -279,6 +279,7 @@ tests-static-normal := \ # tests-static-normal tests-static-internal := \ + tst-atrandom-scrub-static \ tst-dl-printf-static \ tst-dl_find_object-static \ tst-env-setuid-tunables \ @@ -548,6 +549,7 @@ tests-internal += \ neededtest2 \ neededtest3 \ neededtest4 \ + tst-atrandom-scrub \ tst-audit19a \ tst-create_format1 \ tst-dl-hwcaps_split \ @@ -2410,6 +2412,9 @@ tst-ptrguard1-ARGS = --command "$(host-test-program-cmd) --child" CFLAGS-tst-ptrguard1-static.c += -DPTRGUARD_LOCAL tst-ptrguard1-static-ARGS = --command "$(objpfx)tst-ptrguard1-static --child" +# Likewise, the static pointer guard lives in __pointer_chk_guard_local. +CFLAGS-tst-atrandom-scrub-static.c += -DPTRGUARD_LOCAL + $(objpfx)tst-leaks1-mem.out: $(objpfx)tst-leaks1.out $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1.mtrace > $@; \ $(evaluate-test) diff --git a/elf/rtld.c b/elf/rtld.c index 12e1b4dd71f..4d27b2fccc8 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -832,10 +833,7 @@ security_init (void) #endif __pointer_chk_guard_local = pointer_chk_guard; - /* We do not need the _dl_random value anymore. The less - information we leave behind, the better, so clear the - variable. */ - _dl_random = NULL; + _dl_reseed_random (&_dl_random); } #include diff --git a/elf/tst-atrandom-scrub-static.c b/elf/tst-atrandom-scrub-static.c new file mode 100644 index 00000000000..b68362fbb3c --- /dev/null +++ b/elf/tst-atrandom-scrub-static.c @@ -0,0 +1 @@ +#include "tst-atrandom-scrub.c" diff --git a/elf/tst-atrandom-scrub.c b/elf/tst-atrandom-scrub.c new file mode 100644 index 00000000000..1fabfa63dcb --- /dev/null +++ b/elf/tst-atrandom-scrub.c @@ -0,0 +1,74 @@ +/* Verify the AT_RANDOM bytes do not reveal the guards after startup. + Copyright (C) 2026 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 + . */ + +/* The loader (security_init) and the static startup code (__libc_start_main) + derive the stack and pointer guards from the AT_RANDOM bytes, scrub those + bytes, and refill them with fresh entropy unrelated to the guards. The + AT_RANDOM entry is kept, so getauxval (AT_RANDOM) keeps returning 16 random + bytes, but they no longer reveal the guards. Check that neither guard can + be reconstructed from AT_RANDOM and that no auxiliary vector entry holds a + guard value. */ + +#include +#include +#include +#include + +#include +#include +#include + +static int +do_test (void) +{ + uintptr_t stack_guard = STACK_CHK_GUARD; + uintptr_t pointer_guard = POINTER_CHK_GUARD; + + unsigned char *random = (unsigned char *) getauxval (AT_RANDOM); + if (random == NULL) + FAIL_UNSUPPORTED ("the kernel did not provide AT_RANDOM"); + + printf ("debug: stack guard = %0*jx\n", + (int) (2 * sizeof (uintptr_t)), (uintmax_t) stack_guard); + printf ("debug: pointer guard = %0*jx\n", + (int) (2 * sizeof (uintptr_t)), (uintmax_t) pointer_guard); + printf ("debug: AT_RANDOM = "); + for (int i = 0; i < 16; i++) + printf ("%02x", random[i]); + printf ("\n"); + + /* Reconstruct the guards from the (reseeded) AT_RANDOM bytes the way the + loader does and check that they no longer match the live guards. */ + uintptr_t recovered_stack; + memcpy (&recovered_stack, random, sizeof (recovered_stack)); +#if __BYTE_ORDER == __LITTLE_ENDIAN + recovered_stack &= ~(uintptr_t) 0xff; +#else + recovered_stack &= ~((uintptr_t) 0xff << (8 * (sizeof (recovered_stack) - 1))); +#endif + TEST_VERIFY (recovered_stack != stack_guard); + + uintptr_t recovered_pointer; + memcpy (&recovered_pointer, random + sizeof (uintptr_t), + sizeof (recovered_pointer)); + TEST_VERIFY (recovered_pointer != pointer_guard); + + return 0; +} + +#include diff --git a/sysdeps/generic/dl-reseed-random.h b/sysdeps/generic/dl-reseed-random.h new file mode 100644 index 00000000000..7e1a3c3be21 --- /dev/null +++ b/sysdeps/generic/dl-reseed-random.h @@ -0,0 +1,34 @@ +/* Scrub and reseed the kernel-provided random bytes. Generic version. + Copyright (C) 2026 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 _DL_RESEED_RANDOM_H +#define _DL_RESEED_RANDOM_H + +#include + +static inline void __attribute__ ((always_inline)) +_dl_reseed_random (void **dl_random) +{ + if (*dl_random == NULL) + return; + memset (*dl_random, '\0', 16); + __asm__ __volatile__ ("" : : "r" (*dl_random) : "memory"); + *dl_random = NULL; +} + +#endif /* _DL_RESEED_RANDOM_H */ diff --git a/sysdeps/unix/sysv/linux/dl-reseed-random.h b/sysdeps/unix/sysv/linux/dl-reseed-random.h new file mode 100644 index 00000000000..f954e48b7f1 --- /dev/null +++ b/sysdeps/unix/sysv/linux/dl-reseed-random.h @@ -0,0 +1,43 @@ +/* Scrub and reseed the AT_RANDOM bytes. Linux version. + Copyright (C) 2026 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 _DL_RESEED_RANDOM_H +#define _DL_RESEED_RANDOM_H + +#include +#include +#include + +/* The stack and pointer guards have been derived from the 16 AT_RANDOM + bytes pointed to by DL_RANDOM. Scrub them first, so the guards cannot be + recovered even if the refill below fails, then refill them with fresh + entropy unrelated to the guards so that getauxval (AT_RANDOM) keeps + returning random bytes. */ +static inline void __attribute__ ((always_inline)) +_dl_reseed_random (void **dl_random) +{ + if (*dl_random == NULL) + return; + memset (*dl_random, '\0', 16); + __asm__ __volatile__ ("" : : "r" (*dl_random) : "memory"); + + __getrandom_nocancel_nostatus_direct (*dl_random, 16, GRND_NONBLOCK); + _dl_random = NULL; +} + +#endif /* _DL_RESEED_RANDOM_H */