From patchwork Tue Dec 9 17:31:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 126276 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id C78E04BA2E05 for ; Tue, 9 Dec 2025 17:32:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C78E04BA2E05 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=LG8/42b7 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 7EBA54BA2E1C for ; Tue, 9 Dec 2025 17:31:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7EBA54BA2E1C Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7EBA54BA2E1C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1765301509; cv=none; b=rIVxZXZIu3NRD9QjQrs0WkuTLM7GEm6SV86CcJ2geab4oGer1lUtswaTvbFBeqaeZhiG9NvFae6uNtqesLJKcgQzm8d/noSmCOW9NQOUqN1ZVAZDD7mN0L81ZHaOyRCo05Mo0Zg9BisrRuK7P7yuM53b1mb/50XUqp1+peXk+7w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1765301509; c=relaxed/simple; bh=xDWE9ci/tqHK22EL4DDh0iKs9zaAi38lDtq/BjWESZ4=; h=DKIM-Signature:From:To:Subject:Message-ID:Date:MIME-Version; b=btIvTZ0ys/tMaa4TF4Zd6czJFgpmqGzapgWsVdE4WiPnYk2nawaYHlAgVVTSb7iToVBC+pqiWY8P7QxuT1oF2oBdAg35kirgC7VSzkrp0nIcXTSnLJfvym9SiINinef/5SM8ewFcImawYAWPHis0cEhEgnT8e83NdKypBSTvESA= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7EBA54BA2E1C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1765301509; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Amo//EFAjfDdjK/Dq8ozEU5RVPP3p2oLuosg0EhTBRc=; b=LG8/42b71F9teAqLSwAS/ytzvxdUMXtsSq0z06jOSQKUWAdWFBwoP+jRhKrfQ9OooW6sqx hWRYDNXnkEKztXlEB5N78jQgDTmKdwrmGyPcn3fUHpoNWh31eORUdOk7C9hKlD7Fhx3eKj HfIcoXNO8gBMIhxr/+L/aNvSAfEcdlM= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-676-pvLrwgfmPv6mQr_tvqCUAw-1; Tue, 09 Dec 2025 12:31:47 -0500 X-MC-Unique: pvLrwgfmPv6mQr_tvqCUAw-1 X-Mimecast-MFC-AGG-ID: pvLrwgfmPv6mQr_tvqCUAw_1765301506 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B1DBF19560B4 for ; Tue, 9 Dec 2025 17:31:46 +0000 (UTC) Received: from fweimer-oldenburg.csb.redhat.com (unknown [10.45.226.70]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8662B19560A7 for ; Tue, 9 Dec 2025 17:31:45 +0000 (UTC) From: Florian Weimer To: libc-alpha@sourceware.org Subject: [PATCH 4/5] Linux: Implement per-thread user and group IDs In-Reply-To: Message-ID: <73d5eb4fd2bd2b7eb21befaee9094d34648a34b2.1765301308.git.fweimer@redhat.com> References: X-From-Line: 73d5eb4fd2bd2b7eb21befaee9094d34648a34b2 Mon Sep 17 00:00:00 2001 Date: Tue, 09 Dec 2025 18:31:43 +0100 User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: iG0pxDNAcDeBDc8b3StuMQawoBWlr2GwqPZAJe_Gr_w_1765301506 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_BLOCKED, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_NONE, TXREP, URIBL_BLOCKED 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 This commit adds the functions pthread_attr_setperthreadids_np and pthread_attr_getperthreadids_np. Threads created with the new flag will be exempted from the setxid broadcast. setuid and related functions will only update the credentials for the current thread. Multi-threaded file servers typically need this functionality and call the system calls directly to implement this. --- NEWS | 5 + manual/threads.texi | 63 +- nptl/Makefile | 5 + nptl/Versions | 2 + nptl/nptl_setxid.c | 20 +- nptl/pthread_attr_getperthreadids_np.c | 32 ++ nptl/pthread_attr_setperthreadids_np.c | 39 ++ nptl/tst-pthread-perthreadids.c | 541 ++++++++++++++++++ sysdeps/nptl/internaltypes.h | 3 +- sysdeps/nptl/pthread.h | 18 + sysdeps/nptl/pthreadP.h | 8 + sysdeps/nptl/setxid.h | 2 +- sysdeps/unix/sysv/linux/aarch64/libc.abilist | 2 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 2 + sysdeps/unix/sysv/linux/arc/libc.abilist | 2 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 + sysdeps/unix/sysv/linux/csky/libc.abilist | 2 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 2 + sysdeps/unix/sysv/linux/i386/libc.abilist | 2 + .../sysv/linux/loongarch/lp64/libc.abilist | 2 + .../sysv/linux/m68k/coldfire/libc.abilist | 2 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 + .../sysv/linux/microblaze/be/libc.abilist | 2 + .../sysv/linux/microblaze/le/libc.abilist | 2 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 2 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 2 + .../sysv/linux/mips/mips64/n32/libc.abilist | 2 + .../sysv/linux/mips/mips64/n64/libc.abilist | 2 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 2 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 2 + .../powerpc/powerpc32/nofpu/libc.abilist | 2 + .../linux/powerpc/powerpc64/be/libc.abilist | 2 + .../linux/powerpc/powerpc64/le/libc.abilist | 2 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 2 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 2 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 2 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 2 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 + .../sysv/linux/sparc/sparc32/libc.abilist | 2 + .../sysv/linux/sparc/sparc64/libc.abilist | 2 + .../unix/sysv/linux/x86_64/64/libc.abilist | 2 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 2 + 44 files changed, 789 insertions(+), 13 deletions(-) create mode 100644 nptl/pthread_attr_getperthreadids_np.c create mode 100644 nptl/pthread_attr_setperthreadids_np.c create mode 100644 nptl/tst-pthread-perthreadids.c diff --git a/NEWS b/NEWS index 1bd9f8b795..740b9de0e8 100644 --- a/NEWS +++ b/NEWS @@ -63,6 +63,11 @@ Major new features: pthread_attr_setperthreadfs_np and pthread_attr_getperthreadfs_np have been added in support of that. +* On Linux, threads can now be created in such a way that they retain + per-thread user and group IDs. The functions + pthread_attr_setperthreadids_np and pthread_attr_getperthreadids_np have + been added in support of that. + Deprecated and removed features, and other changes affecting compatibility: * Support for dumped heaps has been removed - malloc_set_state() now always diff --git a/manual/threads.texi b/manual/threads.texi index 8df694cc43..902cf5be00 100644 --- a/manual/threads.texi +++ b/manual/threads.texi @@ -1295,11 +1295,12 @@ This property in question is thread-specific. The @code{PTHREAD_PER_THREAD_NP} flag is sticky, in the sense that all threads created by a thread created with this flag have per-thread -properties, even if they are created with the matching thread -attribute set to the @code{PTHREAD_PER_PROCESS_NP} flag. If an -application wants to create new threads sharing properties with the -main thread, it should create a service thread early (perhaps from an -ELF constructor) and create these threads using this service thread. +properties of the requested kind, even if they are created with the +matching thread attribute set to the @code{PTHREAD_PER_PROCESS_NP} +flag. If an application wants to create new threads sharing +properties with the main thread, it should create a service thread +early (perhaps from an ELF constructor) and create these threads using +this service thread. Per-thread properties can be set and examined for an attribute using the functions below. @@ -1361,6 +1362,58 @@ Obtain the per-thread status of the file system properties in This function is a GNU extension and specific to Linux. @end deftypefun +@deftypefun int pthread_attr_setperthreadids_np (pthread_attr_t *@var{attr}, int @var{scope}) +@standards{GNU, pthread.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +Change whether the following properties related to file system access +are made thread-specific when a new thread is created using the +attribute @var{attr}: + +@itemize @bullet +@item +@cindex per-thread user ID +@cindex thread-specific user ID +real, effective and saved user ID (as returned by the +@code{getresuid} function) + +@item +@cindex per-thread group ID +@cindex thread-specific group ID +real, effective and saved group ID (as returned by the +@code{getresgid} function) + +@item +supplementary group list (as returned by the @code{getgroups} +function) +@end itemize + +This function returns zero on success. @var{scope} must be one of the +constants @code{PTHREAD_PER_PROCESS_NP} or +@code{PTHREAD_PER_THREAD_NP}, otherwise the function returns +@code{EINVAL}. + +If @var{scope} is @code{PTHREAD_PER_THREAD_NP}, the attribute will +cause the IDs listed above to be specific to the thread. The initial +values of these IDs are copied from the creating thread, at thread +creation time. + +If a thread that has been created with the +@code{PTHREAD_PER_THREAD_NP} flag creates further threads, these +threads are implicitly created with the @code{PTHREAD_PER_THREAD_NP} +flag, ignoring the value of this thread creation attribute. + +This function is a GNU extension and specific to Linux. +@end deftypefun + +@deftypefun int pthread_attr_getperthreadids_np (pthread_attr_t *restrict @var{attr}, int *restrict @var{scope}) +@standards{GNU, pthread.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +Obtain the per-thread status of user and group IDs in @var{attr} and +store it in the location @var{scope}. + +This function is a GNU extension and specific to Linux. +@end deftypefun + @node Thread CPU Affinity @subsubsection Thread CPU Affinity diff --git a/nptl/Makefile b/nptl/Makefile index 05c6c32a76..3d1848ebea 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -66,6 +66,7 @@ routines = \ pthread_attr_getguardsize \ pthread_attr_getinheritsched \ pthread_attr_getperthreadfs_np \ + pthread_attr_getperthreadids_np \ pthread_attr_getschedparam \ pthread_attr_getschedpolicy \ pthread_attr_getscope \ @@ -79,6 +80,7 @@ routines = \ pthread_attr_setguardsize \ pthread_attr_setinheritsched \ pthread_attr_setperthreadfs_np \ + pthread_attr_setperthreadids_np \ pthread_attr_setschedparam \ pthread_attr_setschedpolicy \ pthread_attr_setscope \ @@ -409,6 +411,9 @@ tests-time64 := \ # and then cause the make process to fail too, see bug 24537. xtests += tst-eintr1 +# This thread calls various set*id functions. +xtests += tst-pthread-perthreadids + test-srcs = tst-oddstacklimit gen-as-const-headers = \ diff --git a/nptl/Versions b/nptl/Versions index c4ff312468..c39faf7fda 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -384,6 +384,8 @@ libc { GLIBC_2.43 { pthread_attr_setperthreadfs_np; pthread_attr_getperthreadfs_np; + pthread_attr_setperthreadids_np; + pthread_attr_getperthreadids_np; } GLIBC_PRIVATE { __libc_alloca_cutoff; diff --git a/nptl/nptl_setxid.c b/nptl/nptl_setxid.c index 3da0d197c7..97caeddec3 100644 --- a/nptl/nptl_setxid.c +++ b/nptl/nptl_setxid.c @@ -22,6 +22,14 @@ #include #include +/* The current thread and threads with per-thread user and group IDs + are not part of the setxid broadcast. */ +static inline bool +thread_excluded_from_setxid_broadcast (struct pthread *self, struct pthread *t) +{ + return t == self || (t->flags & ATTR_FLAG_PERTHREADIDS); +} + /* Check for consistency across set*id system call results. The abort should not happen as long as all privileges changes happen through the glibc wrappers. ERROR must be 0 (no error) or an errno @@ -189,7 +197,7 @@ __nptl_setxid (struct xid_command *cmdp) list_for_each (runp, &GL (dl_stack_used)) { struct pthread *t = list_entry (runp, struct pthread, list); - if (t == self) + if (thread_excluded_from_setxid_broadcast (self, t)) continue; setxid_mark_thread (cmdp, t); @@ -199,7 +207,7 @@ __nptl_setxid (struct xid_command *cmdp) list_for_each (runp, &GL (dl_stack_user)) { struct pthread *t = list_entry (runp, struct pthread, list); - if (t == self) + if (thread_excluded_from_setxid_broadcast (self, t)) continue; setxid_mark_thread (cmdp, t); @@ -215,7 +223,7 @@ __nptl_setxid (struct xid_command *cmdp) list_for_each (runp, &GL (dl_stack_used)) { struct pthread *t = list_entry (runp, struct pthread, list); - if (t == self) + if (thread_excluded_from_setxid_broadcast (self, t)) continue; signalled += setxid_signal_thread (cmdp, t); @@ -224,7 +232,7 @@ __nptl_setxid (struct xid_command *cmdp) list_for_each (runp, &GL (dl_stack_user)) { struct pthread *t = list_entry (runp, struct pthread, list); - if (t == self) + if (thread_excluded_from_setxid_broadcast (self, t)) continue; signalled += setxid_signal_thread (cmdp, t); @@ -245,7 +253,7 @@ __nptl_setxid (struct xid_command *cmdp) list_for_each (runp, &GL (dl_stack_used)) { struct pthread *t = list_entry (runp, struct pthread, list); - if (t == self) + if (thread_excluded_from_setxid_broadcast (self, t)) continue; setxid_unmark_thread (cmdp, t); @@ -254,7 +262,7 @@ __nptl_setxid (struct xid_command *cmdp) list_for_each (runp, &GL (dl_stack_user)) { struct pthread *t = list_entry (runp, struct pthread, list); - if (t == self) + if (thread_excluded_from_setxid_broadcast (self, t)) continue; setxid_unmark_thread (cmdp, t); diff --git a/nptl/pthread_attr_getperthreadids_np.c b/nptl/pthread_attr_getperthreadids_np.c new file mode 100644 index 0000000000..18f88f1f3e --- /dev/null +++ b/nptl/pthread_attr_getperthreadids_np.c @@ -0,0 +1,32 @@ +/* Read the per-thread user/group IDs flag in thread attributes. + Copyright (C) 2025 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 + +int +pthread_attr_getperthreadids_np (const pthread_attr_t *__restrict attr, + int *__restrict scope) +{ + struct pthread_attr *iattr = (struct pthread_attr *) attr; + if (iattr->flags & ATTR_FLAG_PERTHREADIDS) + *scope = PTHREAD_PER_THREAD_NP; + else + *scope = PTHREAD_PER_PROCESS_NP; + return 0; +} diff --git a/nptl/pthread_attr_setperthreadids_np.c b/nptl/pthread_attr_setperthreadids_np.c new file mode 100644 index 0000000000..5385ab0bae --- /dev/null +++ b/nptl/pthread_attr_setperthreadids_np.c @@ -0,0 +1,39 @@ +/* Change the per-thread user/group IDs flag in thread attributes. + Copyright (C) 2025 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 + +int +pthread_attr_setperthreadids_np (pthread_attr_t *attr, int scope) +{ + struct pthread_attr *iattr = (struct pthread_attr *) attr; + switch (scope) + { + case PTHREAD_PER_PROCESS_NP: + iattr->flags &= ~ATTR_FLAG_PERTHREADIDS; + return 0; + break; + case PTHREAD_PER_THREAD_NP: + iattr->flags |= ATTR_FLAG_PERTHREADIDS; + return 0; + default: + return EINVAL; + } +} diff --git a/nptl/tst-pthread-perthreadids.c b/nptl/tst-pthread-perthreadids.c new file mode 100644 index 0000000000..05ed098944 --- /dev/null +++ b/nptl/tst-pthread-perthreadids.c @@ -0,0 +1,541 @@ +/* Test per-thread user and group IDs. + Copyright (C) 2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Return true if the thread has per-thread file system attributes. + Note: This function calls pthread_getattr_np on THR, so the caller + has to ensure that the thread is still running (and not merely + joinable). */ +static bool +perthread_flag (pthread_t thr) +{ + pthread_attr_t attr; + int ret = pthread_getattr_np (thr, &attr); + if (ret != 0) + { + errno = ret; + FAIL_EXIT1 ("pthread_getattr_np: %m"); + } + int flag = -1; + pthread_attr_getperthreadids_np (&attr, &flag); + if (flag != PTHREAD_PER_THREAD_NP) + TEST_COMPARE (flag, PTHREAD_PER_PROCESS_NP); + xpthread_attr_destroy (&attr); + return flag == PTHREAD_PER_THREAD_NP; +} + +/* Which set*id function to call. */ +enum operation +{ + /* No function is called, but the thread will observe changes made by + another thread. */ + OP_NONE, + + OP_SETUID, + OP_SETEUID, + OP_SETREUID, + OP_SETRESUID, + OP_SETGID, + OP_SETEGID, + OP_SETREGID, + OP_SETRESGID, + OP_SETGROUPS, +}; + +/* Convert the operation to a descriptive string. */ +static const char * +operation_string (enum operation op) +{ + switch (op) + { + case OP_NONE: + return ""; + case OP_SETUID: + return "OP_SETUID"; + case OP_SETEUID: + return "OP_SETEUID"; + case OP_SETREUID: + return "OP_SETREUID"; + case OP_SETRESUID: + return "OP_SETRESUID"; + case OP_SETGID: + return "OP_SETGID"; + case OP_SETEGID: + return "OP_SETEGID"; + case OP_SETREGID: + return "OP_SETREGID"; + case OP_SETRESGID: + return "OP_SETRESGID"; + case OP_SETGROUPS: + return "OP_SETGROUPS"; + } + + FAIL_EXIT1 ("invalid operation: %d", (int) op); +} + +/* One test case to perform. */ +struct test_case +{ + enum operation op; + int args[3]; + + /* Expected UIDs and GIDs are only used if the current thread has + made changes. */ + uid_t expected_uid[3]; + gid_t expected_gid[3]; +}; + +#pragma GCC diagnostic push +#pragma GCC diagnostic error "-Wmissing-field-initializers" +static const struct test_case test_cases[] = + { + /* op args expected_gid expected_gid. */ + { OP_NONE, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0} }, + + { OP_SETUID, { 1, 0, 0 }, { 1, 1, 1 }, { 0, 0, 0 } }, + { OP_SETEUID, { 2, 0, 0 }, { 0, 2, 0 }, { 0, 0, 0 } }, + { OP_SETREUID, { 3, 4, 0 }, { 3, 4, 4 }, { 0, 0, 0 } }, + { OP_SETRESUID, { 3, 4, 5 }, { 3, 4, 5 }, { 0, 0, 0 } }, + + { OP_SETGID, { 6, 0, 0 }, { 0, 0, 0 }, { 6, 6, 6 } }, + { OP_SETEGID, { 7, 0, 0 }, { 0, 0, 0 }, { 0, 7, 0 } }, + { OP_SETREGID, { 8, 9, 0 }, { 0, 0, 0 }, { 8, 9, 9 } }, + { OP_SETRESGID, { 10, 11, 12 }, { 0, 0, 0 }, { 10, 11, 12 } }, + + { OP_SETGROUPS, { -1, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, + { OP_SETGROUPS, { 13, -1, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, + { OP_SETGROUPS, { 13, 14, -1 }, { 0, 0, 0 }, { 0, 0, 0 } }, + { OP_SETGROUPS, { 13, 14, 15 }, { 0, 0, 0 }, { 0, 0, 0 } }, + + /* Final round of checks. */ + { OP_NONE, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, + }; +#pragma GCC diagnostic pop + +/* Determine the number of supplementary groups in the test case. */ +static size_t +supplemetary_count (const struct test_case *test) +{ + TEST_COMPARE (test->op, OP_SETGROUPS); + size_t count = 0; + while (count < array_length (test->args)) + { + if (test->args[count] < 0) + break; + ++count; + } + return count; +} + +/* Perform the actions in the test case. */ +static void +test_case_run (const struct test_case *test) +{ + int ret = -1; + switch (test->op) + { + case OP_NONE: + return; + + case OP_SETUID: + ret = setuid (test->args[0]); + break; + case OP_SETEUID: + ret = seteuid (test->args[0]); + break; + case OP_SETREUID: + ret = setreuid (test->args[0], test->args[1]); + break; + case OP_SETRESUID: + ret = setresuid (test->args[0], test->args[1], test->args[2]); + break; + + case OP_SETGID: + ret = setgid (test->args[0]); + break; + case OP_SETEGID: + ret = setegid (test->args[0]); + break; + case OP_SETREGID: + ret = setregid (test->args[0], test->args[1]); + break; + case OP_SETRESGID: + ret = setresgid (test->args[0], test->args[1], test->args[2]); + break; + + case OP_SETGROUPS: + { + gid_t groups[] = { test->args[0], test->args[1], test->args[2] }; + ret = setgroups (supplemetary_count (test), groups); + } + } + + if (ret != 0) + FAIL_EXIT1 ("%s (%d, %d, %d): %m (%d)", + operation_string (test->op), + test->args[0], test->args[1], test->args[2], errno); +} + +/* Used to synchronize between threads changing UIDs/GIDs. */ +static pthread_barrier_t barrier; + +/* Used to avoid interleaving the checking phase between threads. */ +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +/* Argument to the thread. */ +struct thread_argument +{ + size_t thread_index; + + /* Do not actually perform the operation, only verify the result. + Used for threads participating in the setxid broadcast. */ + bool suppress_operation; + + /* Run the actual test in a newly created thread, with default + attributes. */ + bool indirect; + + /* Thread is created with per-thread attributes. */ + bool perthread; +}; + +/* Prepare a heap-allocated thread argument which the started thread + should free. */ +static struct thread_argument * +create_thread_argument (struct thread_argument arg) +{ + struct thread_argument *result = xmalloc (sizeof (*result)); + *result = arg; + return result; +} + +/* An actual test thread. CLOSURE is a pointer to struct + thread_argument, and perform the test according to this + information. */ +static void * +threadfunc (void *closure) +{ + struct thread_argument *arg = closure; + + TEST_COMPARE (perthread_flag (pthread_self ()), arg->perthread); + + if (arg->indirect) + { + /* Only indirect once. */ + arg->indirect = false; + /* Use the default attributes (NULL). This verifies that the + per-thread scope is sticky. */ + return xpthread_join (xpthread_create (NULL, threadfunc, arg)); + } + + const struct test_case *expected = &test_cases[0]; + gid_t expected_supplementary[3] = { -1, -1, -1 }; + int expected_supplementary_count = 0; + + /* (1) Wait until all threads have started up. */ + xpthread_barrier_wait (&barrier); + + for (size_t test_index = 0; test_index < array_length (test_cases); + ++test_index) + { + if (test_index == arg->thread_index) + { + if (test_verbose > 0) + { + if (arg->suppress_operation) + printf ("info: thread %zu suppressing operation\n", + test_index); + else + printf ("info: thread %zu performing operation\n", + test_index); + } + if (!arg->suppress_operation) + test_case_run (&test_cases[test_index]); + + expected = &test_cases[test_index]; + if (test_cases[test_index].op == OP_SETGROUPS) + { + expected_supplementary_count + = supplemetary_count (&test_cases[test_index]); + for (int i = 0; i < expected_supplementary_count; ++i) + expected_supplementary[i] = test_cases[test_index].args[i]; + } + } + + /* (2) Wait until all threads have run the requested test. */ + xpthread_barrier_wait (&barrier); + + xpthread_mutex_lock (&mutex); + + if (test_verbose > 0) + printf ("info: checking phase for thread %zu, test %zu\n", + arg->thread_index, test_index); + uid_t actual_uid[3]; + xgetresuid (&actual_uid[0], &actual_uid[1], &actual_uid[2]); + TEST_COMPARE (actual_uid[0], expected->expected_uid[0]); + TEST_COMPARE (actual_uid[1], expected->expected_uid[1]); + TEST_COMPARE (actual_uid[2], expected->expected_uid[2]); + gid_t actual_gid[3]; + xgetresgid (&actual_gid[0], &actual_gid[1], &actual_gid[2]); + TEST_COMPARE (actual_gid[0], expected->expected_gid[0]); + TEST_COMPARE (actual_gid[1], expected->expected_gid[1]); + TEST_COMPARE (actual_gid[2], expected->expected_gid[2]); + + gid_t actual_supplementary[3]; + gid_t actual_supplementary_count + = getgroups (array_length (actual_supplementary), + actual_supplementary); + TEST_COMPARE (actual_supplementary_count, expected_supplementary_count); + if (actual_supplementary_count > 0) + TEST_COMPARE (actual_supplementary[0], expected_supplementary[0]); + if (actual_supplementary_count > 1) + TEST_COMPARE (actual_supplementary[1], expected_supplementary[1]); + if (actual_supplementary_count > 2) + TEST_COMPARE (actual_supplementary[2], expected_supplementary[2]); + + xpthread_mutex_unlock (&mutex); + + /* (3) Wait until all threads have finished checking their view + of the results. */ + xpthread_barrier_wait (&barrier); + } + + free (arg); + return NULL; +} + +/* Used to create threads with per-thread user/group IDs. */ +static pthread_attr_t attr_perthreadids; + +/* Test which verifies that per-thread IDs are thread-specific. */ +static void +check_perthread (bool indirect) +{ + if (test_verbose > 0) + printf ("info: testing per-thread IDs, %s indirection\n", + indirect ? "with" : "without"); + TEST_VERIFY (!perthread_flag (pthread_self ())); + + /* The main thread and another shared thread count as two extra + threads. */ + xpthread_barrier_init (&barrier, NULL, array_length (test_cases) + 2); + + pthread_t perthread_threads[array_length (test_cases)]; + /* Use thread index zero with OP_NONE for checking only. */ + pthread_t shared_thread + = xpthread_create (NULL, threadfunc, + create_thread_argument ((struct thread_argument) { })); + /* Thread is still runing because it waits on barrier. */ + TEST_VERIFY (!perthread_flag (shared_thread)); + + for (size_t i = 0; i < array_length (test_cases); ++i) + { + struct thread_argument *arg + = create_thread_argument ((struct thread_argument) { + .thread_index = i, .indirect = indirect, .perthread = true }); + perthread_threads[i] + = xpthread_create (&attr_perthreadids, threadfunc, arg); + /* Thread is still runing because it waits on barrier (or it is + blocked joining a thread which does). */ + TEST_VERIFY (perthread_flag (perthread_threads[i])); + } + /* Use thread_index 0 with OP_NONE for checking that the main thread + is unchanged. (This also waits on the barrier.) */ + threadfunc (create_thread_argument ((struct thread_argument) { })); + for (size_t i = 0; i < array_length (test_cases); ++i) + xpthread_join (perthread_threads[i]); + xpthread_join (shared_thread); + + xpthread_barrier_destroy (&barrier); +} + +/* Closure arguments to the subprocess. */ +struct subprocess_argument +{ + size_t broadcast_test_index; + bool broadcast_from_main; + bool indirect; +}; + +/* Setting the broadcast UID is destructive, so we need to run it in a + subprocess. */ +static void +subprocess (void *closure) +{ + struct subprocess_argument *arg = closure; + + if (test_verbose > 0) + printf ("info: testing broadcasting test case %zu," + " %sbroadcasting from main, %s indirection\n", + arg->broadcast_test_index, + arg->broadcast_from_main ? "" : "not ", + arg->indirect ? "with" : "without"); + + /* Main thread and two other shared threads are extras. One + per-thread test is skipped, so there are two extra threads. */ + xpthread_barrier_init (&barrier, NULL, array_length (test_cases) + 2); + + pthread_t perthread_threads[array_length (test_cases)]; + /* Use thread index zero for no-op checking. */ + pthread_t shared_threads[2]; + { + struct thread_argument thread_arg = + { + .thread_index = arg->broadcast_test_index, + .suppress_operation =arg->broadcast_from_main, + }; + shared_threads[0] + = xpthread_create (NULL, threadfunc, + create_thread_argument (thread_arg)); + } + { + struct thread_argument thread_arg = + { + .thread_index = arg->broadcast_test_index, + .suppress_operation = true, + }; + shared_threads[1] + = xpthread_create (NULL, threadfunc, + create_thread_argument (thread_arg)); + } + + for (size_t i = 0; i < array_length (test_cases); ++i) + /* Skip the test which uses broadcasting; it does not use the + per-thread IDs. */ + if (i != arg->broadcast_test_index) + { + struct thread_argument thread_arg = + { + .thread_index = i, + .indirect = arg->indirect, + .perthread = true, + }; + perthread_threads[i] + = xpthread_create (&attr_perthreadids, threadfunc, + create_thread_argument (thread_arg)); + } + + /* Call threadfunc from the main thread. If not broadcasting from + main, only perform checking. */ + { + struct thread_argument thread_arg = + { + .thread_index = arg->broadcast_test_index, + .suppress_operation = !arg->broadcast_from_main, + .indirect = arg->indirect, + }; + threadfunc (create_thread_argument (thread_arg)); + } + for (size_t i = 0; i < array_length (test_cases); ++i) + /* Skip the test which uses broadcasting. */ + if (i != arg->broadcast_test_index) + xpthread_join (perthread_threads[i]); + xpthread_join (shared_threads[0]); + xpthread_join (shared_threads[1]); + + xpthread_barrier_destroy (&barrier); +} + +static int +do_test (void) +{ + if (setuid (0) != 0) + FAIL_EXIT1 ("setuid (0): %m"); + if (setgid (0) != 0) + FAIL_EXIT1 ("setgid (0): %m"); + if (setgroups (0, NULL) != 0) + FAIL_EXIT1 ("setgroups (0, NULL): %m"); + + xpthread_attr_init (&attr_perthreadids); + { + /* Test: Default is PTHREAD_PER_PROCESS_NP. */ + int scope = -1; + TEST_COMPARE (pthread_attr_getperthreadids_np (&attr_perthreadids, &scope), + 0); + TEST_COMPARE (scope, PTHREAD_PER_PROCESS_NP); + + /* Test: The getter shows the effect of the setter. */ + TEST_COMPARE (pthread_attr_setperthreadids_np (&attr_perthreadids, + PTHREAD_PER_THREAD_NP), 0); + scope = -1; + TEST_COMPARE (pthread_attr_getperthreadids_np (&attr_perthreadids, &scope), + 0); + TEST_COMPARE (scope, PTHREAD_PER_THREAD_NP); + + /* Test: Invalid scope values result in an error, without a + change. */ + TEST_COMPARE (pthread_attr_setperthreadids_np (&attr_perthreadids, 2), + EINVAL); + scope = -1; + TEST_COMPARE (pthread_attr_getperthreadids_np (&attr_perthreadids, &scope), + 0); + TEST_COMPARE (scope, PTHREAD_PER_THREAD_NP); + } + + /* Test both the direct and indirect case. Direct is when test + threads are launched with a per-thread attribute. Indirect is + when a thread is first launched with the a per-thread attribute, + but the actual test runs in another sub-thread, created with a + NULL attribute. */ + for (int indirect = 0; indirect < 2; ++indirect) + { + check_perthread (indirect); + + /* Test two scenarios, one where set*id function is called from + the main thread, and other one where it is called from + another thread. */ + for (int broadcast_from_main = 0; broadcast_from_main < 2; + ++broadcast_from_main) + /* Perform each of the test cases once, using a broadcast + set*id operation across multiple threads (those threads + which have per-process scope). */ + for (size_t broadcast_test_index = 0; + broadcast_test_index < array_length (test_cases); + ++broadcast_test_index) + { + struct subprocess_argument arg = + { + .broadcast_test_index = broadcast_test_index, + .broadcast_from_main = broadcast_from_main, + .indirect = indirect, + }; + support_isolate_in_subprocess (subprocess, &arg); + } + } + + xpthread_attr_destroy (&attr_perthreadids); + + return 0; +} + +#include diff --git a/sysdeps/nptl/internaltypes.h b/sysdeps/nptl/internaltypes.h index f291421dc2..a7e6285b46 100644 --- a/sysdeps/nptl/internaltypes.h +++ b/sysdeps/nptl/internaltypes.h @@ -52,6 +52,7 @@ struct pthread_attr #define ATTR_FLAG_POLICY_SET 0x0040 #define ATTR_FLAG_DO_RSEQ 0x0080 #define ATTR_FLAG_PERTHREADFS 0x0100 +#define ATTR_FLAG_PERTHREADIDS 0x0200 /* These flags are not copied from the thread attribute at pthread_create time. */ @@ -62,7 +63,7 @@ struct pthread_attr pthread_create even if they are not specified in the thread attribute. */ #define ATTR_FLAGS_INHERITED \ - ATTR_FLAG_PERTHREADFS + (ATTR_FLAG_PERTHREADFS | ATTR_FLAG_PERTHREADIDS) /* Used to allocate a pthread_attr_t object which is also accessed internally. */ diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h index d2280ddc73..f249444acb 100644 --- a/sysdeps/nptl/pthread.h +++ b/sysdeps/nptl/pthread.h @@ -427,6 +427,24 @@ int pthread_attr_getperthreadfs_np (const pthread_attr_t *__restrict __attr, int *__restrict __scope) __THROW __nonnull ((1, 2)); +/* Change the property in *ATTR which indicates whether the thread has + its own user and group IDs. By default, when the real, effective, + or saved user or group ID is changed by a thread, this affects the + entire process. If a thread is created with this flag set to true, + then changing the IDs within that thread will only affect that + thread, and user and group ID changes in other threads (whether + they have enabled this flag or not) do not affect it. If a thread + has been created with this flag, threads created by it will also + have their own, private user and group IDs. */ +int pthread_attr_setperthreadids_np (pthread_attr_t *__attr, int __scope) + __THROW __nonnull ((1)); + +/* Get the per-thread/per-process scope of user and group IDs from + *ATTR and store it in *SCOPE. */ +int pthread_attr_getperthreadids_np (const pthread_attr_t *__restrict __attr, + int *__restrict __scope) + __THROW __nonnull ((1, 2)); + /* Get the default attributes used by pthread_create in this process. */ extern int pthread_getattr_default_np (pthread_attr_t *__attr) __THROW __nonnull ((1)); diff --git a/sysdeps/nptl/pthreadP.h b/sysdeps/nptl/pthreadP.h index 4f649267b3..899aabe10b 100644 --- a/sysdeps/nptl/pthreadP.h +++ b/sysdeps/nptl/pthreadP.h @@ -694,6 +694,14 @@ check_stacksize_attr (size_t st) return EINVAL; } +/* Return true if the current thread has per-thread user and group + IDS. */ +static inline bool +nptl_current_thread_has_separate_ids (void) +{ + return THREAD_SELF->flags & ATTR_FLAG_PERTHREADIDS; +} + #define ASSERT_TYPE_SIZE(type, size) \ _Static_assert (sizeof (type) == size, \ "sizeof (" #type ") != " #size) diff --git a/sysdeps/nptl/setxid.h b/sysdeps/nptl/setxid.h index b1ef6ba0a1..113f3965bf 100644 --- a/sysdeps/nptl/setxid.h +++ b/sysdeps/nptl/setxid.h @@ -29,7 +29,7 @@ #define INLINE_SETXID_SYSCALL(name, nr, args...) \ ({ \ int __result; \ - if (!SINGLE_THREAD_P) \ + if (!SINGLE_THREAD_P && !nptl_current_thread_has_separate_ids ()) \ { \ struct xid_command __cmd; \ __cmd.syscall_no = __NR_##name; \ diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index abc893d3c2..3765780293 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2775,5 +2775,7 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 08ac8d8e1b..c4a09e889a 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -3122,7 +3122,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index 69f616cead..f1a6f708b9 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2536,5 +2536,7 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 9d1678320e..df7b436bdb 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -2828,7 +2828,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index 4f3b5affe9..86504cf679 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -2825,7 +2825,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 4775926d0d..614fcb6d22 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2812,5 +2812,7 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index d3b8ac7de6..06cfb5abc1 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2849,7 +2849,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 7bf6d848df..f671d3861d 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -3032,7 +3032,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index 4438857731..d59b092fda 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2296,5 +2296,7 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 1ec5185e2a..fe9e65fefa 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -2808,7 +2808,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index d091f52f10..8baa152f32 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2975,7 +2975,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index eda99f79cc..450519cdb6 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2861,5 +2861,7 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 28d85c9a69..1c31ad4aef 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2858,5 +2858,7 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 52c206e514..928cb8eb72 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2938,7 +2938,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index fa6b7532bd..461ccf23d5 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2936,7 +2936,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index c2a0b18359..9817b9074d 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2944,7 +2944,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 8c0e99fb18..331915f9d7 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2846,7 +2846,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index 1158bb10d6..7cd7e25f7d 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2286,5 +2286,7 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index bf9faed11f..58f5df6288 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -3165,7 +3165,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index 7dbe21ba65..535afe8021 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -3210,7 +3210,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 8e8a179363..2446a762af 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2919,7 +2919,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 04fa4568bb..dee01554a9 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2995,5 +2995,7 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index 78d4f1f22f..7b2b47e530 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2539,5 +2539,7 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index ae0f2ccac9..92191a7c77 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2739,5 +2739,7 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 7b7c81a68b..3c19286585 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -3163,7 +3163,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 7c81be27f4..3b351b93a1 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2956,7 +2956,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index f04f22b538..a460714b52 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2855,7 +2855,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index ec831f0ad5..333179ee41 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2852,7 +2852,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 4f40e294fe..b7a38f1682 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -3186,7 +3186,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index da128a940a..35ee2aed47 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2822,7 +2822,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 3f32a83378..443fbd58ee 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2771,7 +2771,9 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 8105eaadba..34267354b7 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2790,5 +2790,7 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 pthread_attr_getperthreadfs_np F +GLIBC_2.43 pthread_attr_getperthreadids_np F GLIBC_2.43 pthread_attr_setperthreadfs_np F +GLIBC_2.43 pthread_attr_setperthreadids_np F GLIBC_2.43 umaxabs F