From patchwork Tue Jul 6 14:58:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44174 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4657E388A826 for ; Tue, 6 Jul 2021 15:11:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4657E388A826 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1625584301; bh=Hn68e9QCzMfsuszC6kuLzDrxgtBrxOqTXwvCA8H/GQs=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=XsrhVZk37JPv/zYgGwV7S6pnTHSuWHxq7443/Wn9uwB0T139qYyMPjm15SzVMyRFH 7QF4UamdFJ9u99aSUztGp5Oe0wHKZWt0r5hASUym+zSlUqJ5pWF99o0t0fzWr0pTwL JThsPqksOZelPWxZ50KnKa4UeSmR+AEg7n1X1IyY= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) by sourceware.org (Postfix) with ESMTPS id 390E13888C58 for ; Tue, 6 Jul 2021 14:58:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 390E13888C58 Received: by mail-pf1-x433.google.com with SMTP id y4so19676555pfi.9 for ; Tue, 06 Jul 2021 07:58:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Hn68e9QCzMfsuszC6kuLzDrxgtBrxOqTXwvCA8H/GQs=; b=Og5dHar0hdl0Aw6zMH6dZZf5ll1nAQ5ahlm84+V9/Yqxp/svNEjsMBl7m6QqkZku/s 6snnzmH6dCd8X2GQGwTTzckQM1wjbaamCAG35EX7BxyiM5eP5zpLDD1iVawh0IueZsQ4 w1crpeRcOjcP+k1ZsyV9ciqQaMv5Y7iJiCI83LhBXX87D/jj0QIv6GhlhypvYbOptLXm 8SFFLf7drxS2PLBSZJUWRP1LNZScLUDjM05Wa7dxHiGDBOCTdk12waNcy/6FCuK82Ved o5gsRJgVeDirwmB6yqLIMVkYC8SJsg9SWNxerau4dtC5lzvJ8Z/9sjeL1C5DvwRuNzf3 Nmlw== X-Gm-Message-State: AOAM533NfbXXgJfQcoAChd5B19rAwwpF/hDbmVHu7q0dcf5ubjgpfGXZ pzVoxjVanvufE98A3l2pOzy2xla71BEu7w== X-Google-Smtp-Source: ABdhPJy/RVtOoQFBGNFFCE4mjQN9r+O5fkdb7xzn1o8VBHkqGg0+ufihsBvZRUEvOYjZapuBPBX+Lw== X-Received: by 2002:a62:bd15:0:b029:31c:a584:5f97 with SMTP id a21-20020a62bd150000b029031ca5845f97mr14387272pff.33.1625583526051; Tue, 06 Jul 2021 07:58:46 -0700 (PDT) Received: from birita.. ([177.194.59.218]) by smtp.gmail.com with ESMTPSA id n23sm19018488pgv.76.2021.07.06.07.58.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jul 2021 07:58:45 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v7 1/4] support: Add support_stack_alloc Date: Tue, 6 Jul 2021 11:58:36 -0300 Message-Id: <20210706145839.1658623-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210706145839.1658623-1-adhemerval.zanella@linaro.org> References: <20210706145839.1658623-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_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Changes from previous version: - Handle executable stacks. This is required on architecture where the PT_GNU_STACK is not fully supported (such as hppa). Ideally the function should use GL (dl_stack_flags) to check if the stack should be executable, however accessing the information would required a larger refactor on ldsodefs.h to provide the required prototypes for libsupport. --- The code to allocate a stack from xsigstack is refactored so it can be more generic. The new support_stack_alloc() also set PROT_EXEC if DEFAULT_STACK_PERMS has PF_X. This is required on some architectures (hppa for instance) and trying to access the rtld global from testsuite will require more intrusive refactoring in the ldsodefs.h header. Checked on x86_64-linux-gnu and i686-linux-gnu. I also ran tst-xsigstack on both hppa and ia64. --- support/Makefile | 1 + support/support.h | 19 +++++++++ support/support_stack_alloc.c | 79 +++++++++++++++++++++++++++++++++++ support/xsigstack.c | 43 +++---------------- 4 files changed, 104 insertions(+), 38 deletions(-) create mode 100644 support/support_stack_alloc.c diff --git a/support/Makefile b/support/Makefile index 5c69f0de4b..a462781718 100644 --- a/support/Makefile +++ b/support/Makefile @@ -39,6 +39,7 @@ libsupport-routines = \ resolv_response_context_free \ resolv_test \ set_fortify_handler \ + support_stack_alloc \ support-xfstat \ support-xfstat-time64 \ support-xstat \ diff --git a/support/support.h b/support/support.h index 9ec8ecb8d7..dbd270c78d 100644 --- a/support/support.h +++ b/support/support.h @@ -164,6 +164,25 @@ timer_t support_create_timer (uint64_t sec, long int nsec, bool repeat, /* Disable the timer TIMER. */ void support_delete_timer (timer_t timer); +struct support_stack +{ + void *stack; + size_t size; + size_t guardsize; +}; + +/* Allocate stack suitable to used with xclone or sigaltstack call. The stack + will have a minimum size of SIZE + MINSIGSTKSZ bytes, rounded up to a whole + number of pages. There will be a large (at least 1 MiB) inaccessible guard + bands on either side of it. + The returned value on ALLOC_BASE and ALLOC_SIZE will be the usable stack + region, excluding the GUARD_SIZE allocated area. + It also terminates the process on error. */ +struct support_stack support_stack_alloc (size_t size); + +/* Deallocate the STACK. */ +void support_stack_free (struct support_stack *stack); + __END_DECLS #endif /* SUPPORT_H */ diff --git a/support/support_stack_alloc.c b/support/support_stack_alloc.c new file mode 100644 index 0000000000..db0d522f2f --- /dev/null +++ b/support/support_stack_alloc.c @@ -0,0 +1,79 @@ +/* Allocate a stack suitable to be used with xclone or xsigaltstack. + Copyright (C) 2021 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 /* roundup, MAX */ + +#ifndef MAP_NORESERVE +# define MAP_NORESERVE 0 +#endif +#ifndef MAP_STACK +# define MAP_STACK 0 +#endif + +struct support_stack +support_stack_alloc (size_t size) +{ + size_t pagesize = sysconf (_SC_PAGESIZE); + if (pagesize == -1) + FAIL_EXIT1 ("sysconf (_SC_PAGESIZE): %m\n"); + + /* Always supply at least MINSIGSTKSZ space; passing 0 as size means + only that much space. No matter what the number is, round it up + to a whole number of pages. */ + size_t stacksize = roundup (size + MINSIGSTKSZ, pagesize); + + /* The guard bands need to be large enough to intercept offset + accesses from a stack address that might otherwise hit another + mapping. Make them at least twice as big as the stack itself, to + defend against an offset by the entire size of a large + stack-allocated array. The minimum is 1MiB, which is arbitrarily + chosen to be larger than any "typical" wild pointer offset. + Again, no matter what the number is, round it up to a whole + number of pages. */ + size_t guardsize = roundup (MAX (2 * stacksize, 1024 * 1024), pagesize); + size_t alloc_size = guardsize + stacksize + guardsize; + /* Use MAP_NORESERVE so that RAM will not be wasted on the guard + bands; touch all the pages of the actual stack before returning, + so we know they are allocated. */ + void *alloc_base = xmmap (0, + alloc_size, + PROT_NONE, + MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE|MAP_STACK, + -1); + /* PF_X can be overridden if PT_GNU_STACK is present. */ + int prot = PROT_READ | PROT_WRITE + | (DEFAULT_STACK_PERMS & PF_X ? PROT_EXEC : 0); + xmprotect (alloc_base + guardsize, stacksize, prot); + memset (alloc_base + guardsize, 0xA5, stacksize); + return (struct support_stack) { alloc_base + guardsize, stacksize, guardsize }; +} + +void +support_stack_free (struct support_stack *stack) +{ + void *alloc_base = (void *)((uintptr_t) stack->stack - stack->guardsize); + size_t alloc_size = stack->size + 2 * stack->guardsize; + xmunmap (alloc_base, alloc_size); +} diff --git a/support/xsigstack.c b/support/xsigstack.c index a2f0e3269a..a471c853cb 100644 --- a/support/xsigstack.c +++ b/support/xsigstack.c @@ -37,8 +37,7 @@ structures. */ struct sigstack_desc { - void *alloc_base; /* Base address of the complete allocation. */ - size_t alloc_size; /* Size of the complete allocation. */ + struct support_stack stack; stack_t alt_stack; /* The address and size of the stack itself. */ stack_t old_stack; /* The previous signal stack. */ }; @@ -46,43 +45,11 @@ struct sigstack_desc void * xalloc_sigstack (size_t size) { - size_t pagesize = sysconf (_SC_PAGESIZE); - if (pagesize == -1) - FAIL_EXIT1 ("sysconf (_SC_PAGESIZE): %m\n"); - - /* Always supply at least MINSIGSTKSZ space; passing 0 as size means - only that much space. No matter what the number is, round it up - to a whole number of pages. */ - size_t stacksize = roundup (size + MINSIGSTKSZ, pagesize); - - /* The guard bands need to be large enough to intercept offset - accesses from a stack address that might otherwise hit another - mapping. Make them at least twice as big as the stack itself, to - defend against an offset by the entire size of a large - stack-allocated array. The minimum is 1MiB, which is arbitrarily - chosen to be larger than any "typical" wild pointer offset. - Again, no matter what the number is, round it up to a whole - number of pages. */ - size_t guardsize = roundup (MAX (2 * stacksize, 1024 * 1024), pagesize); - struct sigstack_desc *desc = xmalloc (sizeof (struct sigstack_desc)); - desc->alloc_size = guardsize + stacksize + guardsize; - /* Use MAP_NORESERVE so that RAM will not be wasted on the guard - bands; touch all the pages of the actual stack before returning, - so we know they are allocated. */ - desc->alloc_base = xmmap (0, - desc->alloc_size, - PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE|MAP_STACK, - -1); - - xmprotect (desc->alloc_base, guardsize, PROT_NONE); - xmprotect (desc->alloc_base + guardsize + stacksize, guardsize, PROT_NONE); - memset (desc->alloc_base + guardsize, 0xA5, stacksize); - - desc->alt_stack.ss_sp = desc->alloc_base + guardsize; + desc->stack = support_stack_alloc (size); + desc->alt_stack.ss_sp = desc->stack.stack; desc->alt_stack.ss_flags = 0; - desc->alt_stack.ss_size = stacksize; + desc->alt_stack.ss_size = desc->stack.size; if (sigaltstack (&desc->alt_stack, &desc->old_stack)) FAIL_EXIT1 ("sigaltstack (new stack: sp=%p, size=%zu, flags=%u): %m\n", @@ -101,7 +68,7 @@ xfree_sigstack (void *stack) FAIL_EXIT1 ("sigaltstack (restore old stack: sp=%p, size=%zu, flags=%u): " "%m\n", desc->old_stack.ss_sp, desc->old_stack.ss_size, desc->old_stack.ss_flags); - xmunmap (desc->alloc_base, desc->alloc_size); + support_stack_free (&desc->stack); free (desc); } From patchwork Tue Jul 6 14:58:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44175 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 63F4B388E839 for ; Tue, 6 Jul 2021 15:12:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 63F4B388E839 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1625584346; bh=EvglTjfJLoYFYIHB9js8gh0eoeCl9L91wNByOphfOsc=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=mk8YFX0gnmNNOEQOutj5M4U1tQcIot+TTAdFlntzGbzLWg2pGmWYigBC9jng6uHUX WS4/VXLGOC4ZY3oOcnXodF66FaDwfoEaivGGb9ySyLPEPxoLQz8SqV4HlqTDOzBPsB ODEyUYsnX7GFXJZL7s3qjqzCeQpkiCnpyIloXhs4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by sourceware.org (Postfix) with ESMTPS id CE5C4388F005 for ; Tue, 6 Jul 2021 14:58:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CE5C4388F005 Received: by mail-pg1-x52d.google.com with SMTP id y17so21612554pgf.12 for ; Tue, 06 Jul 2021 07:58:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EvglTjfJLoYFYIHB9js8gh0eoeCl9L91wNByOphfOsc=; b=EulFMdyA0WmXr2UJW4e8IwWYOFzgQzPR355iz5D1yhzrdPS5BNrm39gSVnFeWiHnNV b4BpaS7s/Re5zzYANzK2rePaL6DdZ9vdobiZWUp77Gj1DZcffbSBQk+aql7dv0vx5H6a b3Zx8etcBw0UtKYHURVwOWc+kfCzSMD4t2B8X0QrSFIEr59u63qASkK064La/k78dNIR e+CZ3PteQcZtlLNyKsaJWoIpX5jHlqVCieuXOcrAzV1WA1nVWVdHX06Ql+m5nKxahVhw oE5wS7gApmNobjae83vadDANeSEITLy2I6Vs3SGB5LOJUT3Yb3KXjCR6EictlYoKKAu9 2+Fg== X-Gm-Message-State: AOAM5313xVmwbk7+8eykrTjj8om1TooW+Cjv0WoVq9af648I/KNupi1I fdpe77AI9ODJNoP1yNYwRbfy27eRO74Lkg== X-Google-Smtp-Source: ABdhPJxnsM6nFfKYveQKtyiiAyMd112bff88PqRAiPBNmK2hp/tBmw3+hxRy9r50RZnPvNpgYbFXTQ== X-Received: by 2002:a65:6704:: with SMTP id u4mr21255108pgf.140.1625583527449; Tue, 06 Jul 2021 07:58:47 -0700 (PDT) Received: from birita.. ([177.194.59.218]) by smtp.gmail.com with ESMTPSA id n23sm19018488pgv.76.2021.07.06.07.58.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jul 2021 07:58:47 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v7 2/4] linux: Add close_range Date: Tue, 6 Jul 2021 11:58:37 -0300 Message-Id: <20210706145839.1658623-3-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210706145839.1658623-1-adhemerval.zanella@linaro.org> References: <20210706145839.1658623-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_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Changes from previous version: - Fixed manual entry and added ENOSYS returned code. --- It was added on Linux 5.9 (278a5fbaed89) with CLOSE_RANGE_CLOEXEC added on 5.11 (582f1fb6b721f). Although FreeBSD has added the same syscall, this only adds the symbol on Linux ports. This syscall is required to provided a fail-safe way to implement the closefrom symbol (BZ #10353). Checked on x86_64-linux-gnu on kernel v5.9 and v5.4. --- NEWS | 3 + include/bits/unistd_ext.h | 6 + manual/llio.texi | 49 +++ sysdeps/unix/sysv/linux/Makefile | 3 +- sysdeps/unix/sysv/linux/Versions | 1 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/bits/unistd_ext.h | 22 ++ sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + sysdeps/unix/sysv/linux/syscalls.list | 1 + sysdeps/unix/sysv/linux/tst-close_range.c | 303 ++++++++++++++++++ .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 40 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 include/bits/unistd_ext.h create mode 100644 sysdeps/unix/sysv/linux/tst-close_range.c diff --git a/NEWS b/NEWS index 8e72946c3f..be04b217fe 100644 --- a/NEWS +++ b/NEWS @@ -60,6 +60,9 @@ Major new features: to call async-signal-safe functions (such as raise or execve). This function is currently a GNU extension. +* On Linux, the close_range function has been added. It allows efficiently + closing a range of file descriptors on recent kernels (version 5.9). + Deprecated and removed features, and other changes affecting compatibility: * The function pthread_mutex_consistent_np has been deprecated; programs diff --git a/include/bits/unistd_ext.h b/include/bits/unistd_ext.h new file mode 100644 index 0000000000..277be05746 --- /dev/null +++ b/include/bits/unistd_ext.h @@ -0,0 +1,6 @@ +#include_next + +#ifndef _ISOMAC +extern int __close_range (unsigned int lowfd, unsigned int highfd, int flags); +libc_hidden_proto (__close_range); +#endif diff --git a/manual/llio.texi b/manual/llio.texi index eafc27120d..ea6d34dd5a 100644 --- a/manual/llio.texi +++ b/manual/llio.texi @@ -284,6 +284,55 @@ of trying to close its underlying file descriptor with @code{close}. This flushes any buffered output and updates the stream object to indicate that it is closed. +@deftypefun int close_range (unsigned int @var{lowfd}, unsigned int @var{maxfd}, int @var{flags}) +@standards{Linux, unistd.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} +@c This is a syscall for Linux v5.9. There is no fallback emulation for +@c older kernels. + +The function @code{close_range} closes the file descriptor from @var{lowfd} +to @var{maxfd} (inclusive). This function is similar to call @code{close} in +specified file descriptor range depending on the @var{flags}. + +This is function is only supported on recent Linux versions and @theglibc{} +does not provide any fallback (the application will need to handle possible +@code{ENOSYS}). + +The @var{flags} add options on how the files are closes. Linux currently +supports: + +@vtable @code +@item CLOSE_RANGE_UNSHARE +Unshare the file descriptor table before closing file descriptors. + +@item CLOSE_RANGE_CLOEXEC +Set the @code{FD_CLOEXEC} bit instead of closing the file descriptor. +@end vtable + +The normal return value from @code{close_range} is @math{0}; a value +of @math{-1} is returned in case of failure. The following @code{errno} error +conditions are defined for this function: + +@table @code +@item EINVAL +The @var{lowfd} value is larger than @var{maxfd} or an unsupported @var{flags} +is used. + +@item ENOMEM +Either there is not enough memory for the operation, or the process is +out of address space. + +@item EMFILE +The process has too many files open. +The maximum number of file descriptors is controlled by the +@code{RLIMIT_NOFILE} resource limit; @pxref{Limits on Resources}. + +@item ENOSYS +The kernel does not implement the required functionality. +@end table +@end deftypefun + + @node I/O Primitives @section Input and Output Primitives diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index faea02bd1b..e308711168 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -116,7 +116,8 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ tst-tgkill tst-sysvsem-linux tst-sysvmsg-linux tst-sysvshm-linux \ tst-timerfd tst-ppoll \ tst-clock_adjtime tst-adjtimex tst-ntp_adjtime tst-ntp_gettime \ - tst-ntp_gettimex tst-sigtimedwait tst-misalign-clone + tst-ntp_gettimex tst-sigtimedwait tst-misalign-clone \ + tst-close_range # Test for the symbol version of fcntl that was replaced in glibc 2.28. ifeq ($(have-GLIBC_2.27)$(build-shared),yesyes) diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 53cb7b23e2..4884216825 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -283,6 +283,7 @@ libc { __wait3_time64; __wait4_time64; %endif + close_range; } GLIBC_PRIVATE { # functions used in other libraries diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 6730cbdd6b..c32f5898fe 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2409,6 +2409,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 63de4fadc3..cb10eadbb9 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2508,6 +2508,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index 2f13701fd7..a697c930e1 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2168,6 +2168,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 9b824f1605..7dbe38dcb7 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -302,6 +302,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index 443a81b8f7..0ee69506ea 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -299,6 +299,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/bits/unistd_ext.h b/sysdeps/unix/sysv/linux/bits/unistd_ext.h index 2e529be577..bf313e8af8 100644 --- a/sysdeps/unix/sysv/linux/bits/unistd_ext.h +++ b/sysdeps/unix/sysv/linux/bits/unistd_ext.h @@ -33,4 +33,26 @@ not detached and has not been joined. */ extern __pid_t gettid (void) __THROW; +#ifdef __has_include +# if __has_include ("linux/close_range.h") +# include "linux/close_range.h" +# endif #endif +/* Unshare the file descriptor table before closing file descriptors. */ +#ifndef CLOSE_RANGE_UNSHARE +# define CLOSE_RANGE_UNSHARE (1U << 1) +#endif +/* Set the FD_CLOEXEC bit instead of closing the file descriptor. */ +#ifndef CLOSE_RANGE_CLOEXEC +# define CLOSE_RANGE_CLOEXEC (1U << 2) +#endif + +/* Close all file descriptors in the range FD up to MAX_FD. The flag FLAGS + are define by the CLOSE_RANGE prefix. This function behaves like close + on the range, but in a fail-safe where it will either fail and not close + any file descriptor or close all of them. Returns 0 on successor or -1 + for failure (and sets errno accordingly). */ +extern int close_range (unsigned int __fd, unsigned int __max_fd, + int __flags) __THROW; + +#endif /* __USE_GNU */ diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 243de3cf93..c5849e1da2 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2434,6 +2434,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 24ae58bb6f..9368379d9d 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2387,6 +2387,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 09bebcd5a1..e4a16d0bcf 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2571,6 +2571,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 0bafe09253..f7a29d00de 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2346,6 +2346,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index c1fcde4c24..7a1b38fe81 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -303,6 +303,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 407651cfd7..64591d99cc 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2514,6 +2514,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 7da722a734..1769dc5c80 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2485,6 +2485,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index c374607b81..4373d181fb 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2482,6 +2482,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index b1f426e053..c714662ff3 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2479,6 +2479,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 066ceb2258..d6d9f3b5f6 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2477,6 +2477,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 51c563ebbe..287fc03201 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2485,6 +2485,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 28db715d8a..92dc711ee2 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2397,6 +2397,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index ab9f2bd42c..b1c4e54a70 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2524,6 +2524,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 83f8513e17..1ed9e1c9a7 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2541,6 +2541,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index 0fad357bf6..953e05cc33 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2574,6 +2574,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 424ec8d953..e6bcab06d5 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2310,6 +2310,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 9909fd0e9a..525cb85de2 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2605,6 +2605,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index 7085989b16..a1d89d2f14 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2170,6 +2170,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index a855997957..84f7a8561a 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2370,6 +2370,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 12aeb82520..edd1dbbbdb 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2539,6 +2539,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index e2d746ad5f..19160f33ba 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2347,6 +2347,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 1ce4b54bf2..8e99b18060 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2394,6 +2394,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index 7d01add713..f876e152b7 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2391,6 +2391,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index b5ef3247d7..a6fa1a1b29 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2534,6 +2534,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 14ae7c8417..4f6166a8f1 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2369,6 +2369,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 62329abb49..29899eb264 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -99,3 +99,4 @@ pkey_alloc EXTRA pkey_alloc i:ii pkey_alloc pkey_free EXTRA pkey_free i:i pkey_free gettid EXTRA gettid Ei: __gettid gettid tgkill EXTRA tgkill i:iii __tgkill tgkill +close_range EXTRA close_range i:iii __close_range close_range diff --git a/sysdeps/unix/sysv/linux/tst-close_range.c b/sysdeps/unix/sysv/linux/tst-close_range.c new file mode 100644 index 0000000000..dccb6189c5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-close_range.c @@ -0,0 +1,303 @@ +/* Test for the close_range system call. + Copyright (C) 2021 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 +#include + +#define NFDS 100 + +static int +open_multiple_temp_files (void) +{ + /* Check if the temporary file descriptor has no no gaps. */ + int lowfd = xopen ("/dev/null", O_RDONLY, 0600); + for (int i = 1; i <= NFDS; i++) + TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), + lowfd + i); + return lowfd; +} + +static void +close_range_test_max_upper_limit (void) +{ + struct support_descriptors *descrs = support_descriptors_list (); + + int lowfd = open_multiple_temp_files (); + + { + int r = close_range (lowfd, ~0U, 0); + if (r == -1 && errno == ENOSYS) + FAIL_UNSUPPORTED ("close_range not supported"); + TEST_COMPARE (r, 0); + } + + support_descriptors_check (descrs); + support_descriptors_free (descrs); +} + +static void +close_range_test_common (int lowfd, unsigned int flags) +{ + const int maximum_fd = lowfd + NFDS; + const int half_fd = lowfd + NFDS / 2; + const int gap_1 = maximum_fd - 8; + + /* Close half of the descriptors and check result. */ + TEST_COMPARE (close_range (lowfd, half_fd, flags), 0); + for (int i = lowfd; i <= half_fd; i++) + { + TEST_COMPARE (fcntl (i, F_GETFL), -1); + TEST_COMPARE (errno, EBADF); + } + for (int i = half_fd + 1; i < maximum_fd; i++) + TEST_VERIFY (fcntl (i, F_GETFL) > -1); + + /* Create some gaps, close up to a threshold, and check result. */ + xclose (lowfd + 57); + xclose (lowfd + 78); + xclose (lowfd + 81); + xclose (lowfd + 82); + xclose (lowfd + 84); + xclose (lowfd + 90); + + TEST_COMPARE (close_range (half_fd + 1, gap_1, flags), 0); + for (int i = half_fd + 1; i < gap_1; i++) + { + TEST_COMPARE (fcntl (i, F_GETFL), -1); + TEST_COMPARE (errno, EBADF); + } + for (int i = gap_1 + 1; i < maximum_fd; i++) + TEST_VERIFY (fcntl (i, F_GETFL) > -1); + + /* Close the remaining but the last one. */ + TEST_COMPARE (close_range (gap_1 + 1, maximum_fd - 1, flags), 0); + for (int i = gap_1 + 1; i < maximum_fd - 1; i++) + { + TEST_COMPARE (fcntl (i, F_GETFL), -1); + TEST_COMPARE (errno, EBADF); + } + TEST_VERIFY (fcntl (maximum_fd, F_GETFL) > -1); + + /* Close the last one. */ + TEST_COMPARE (close_range (maximum_fd, maximum_fd, flags), 0); + TEST_COMPARE (fcntl (maximum_fd, F_GETFL), -1); + TEST_COMPARE (errno, EBADF); +} + +/* Basic tests: check if the syscall close ranges with and without gaps. */ +static void +close_range_test (void) +{ + struct support_descriptors *descrs = support_descriptors_list (); + + /* Check if the temporary file descriptor has no no gaps. */ + int lowfd = open_multiple_temp_files (); + + close_range_test_common (lowfd, 0); + + /* Double check by check the /proc. */ + support_descriptors_check (descrs); + support_descriptors_free (descrs); +} + +_Noreturn static int +close_range_test_fn (void *arg) +{ + int lowfd = (int) ((uintptr_t) arg); + close_range_test_common (lowfd, 0); + exit (EXIT_SUCCESS); +} + +/* Check if a clone_range on a subprocess created with CLONE_FILES close + the shared file descriptor table entries in the parent. */ +static void +close_range_test_subprocess (void) +{ + struct support_descriptors *descrs = support_descriptors_list (); + + /* Check if the temporary file descriptor has no no gaps. */ + int lowfd = open_multiple_temp_files (); + + struct support_stack stack = support_stack_alloc (4096); + + pid_t pid = xclone (close_range_test_fn, (void*) (uintptr_t) lowfd, + stack.stack, stack.size, CLONE_FILES | SIGCHLD); + TEST_VERIFY_EXIT (pid > 0); + int status; + xwaitpid (pid, &status, 0); + TEST_VERIFY (WIFEXITED (status)); + TEST_COMPARE (WEXITSTATUS (status), 0); + + support_stack_free (&stack); + + for (int i = lowfd; i < NFDS; i++) + TEST_VERIFY (fcntl (i, F_GETFL) < 0); + + support_descriptors_check (descrs); + support_descriptors_free (descrs); +} + + +_Noreturn static int +close_range_unshare_test_fn (void *arg) +{ + int lowfd = (int) ((uintptr_t) arg); + close_range_test_common (lowfd, CLOSE_RANGE_UNSHARE); + exit (EXIT_SUCCESS); +} + +/* Check if a close_range with CLOSE_RANGE_UNSHARE issued from a subprocess + created with CLONE_FILES does not close the parent file descriptor list. */ +static void +close_range_unshare_test (void) +{ + struct support_descriptors *descrs1 = support_descriptors_list (); + + /* Check if the temporary file descriptor has no no gaps. */ + int lowfd = open_multiple_temp_files (); + + struct support_descriptors *descrs2 = support_descriptors_list (); + + struct support_stack stack = support_stack_alloc (4096); + + pid_t pid = xclone (close_range_unshare_test_fn, (void*) (uintptr_t) lowfd, + stack.stack, stack.size, CLONE_FILES | SIGCHLD); + TEST_VERIFY_EXIT (pid > 0); + int status; + xwaitpid (pid, &status, 0); + TEST_VERIFY (WIFEXITED (status)); + TEST_COMPARE (WEXITSTATUS (status), 0); + + support_stack_free (&stack); + + for (int i = 0; i < NFDS; i++) + TEST_VERIFY (fcntl (i, F_GETFL) > -1); + + support_descriptors_check (descrs2); + support_descriptors_free (descrs2); + + TEST_COMPARE (close_range (lowfd, lowfd + NFDS, 0), 0); + + support_descriptors_check (descrs1); + support_descriptors_free (descrs1); +} + +static bool +is_in_array (int *arr, size_t len, int fd) +{ + bool r = false; + for (int i = 0; i < len; i++) + if (arr[i] == fd) + return true; + return r; +} + +static void +close_range_cloexec_test (void) +{ + /* Check if the temporary file descriptor has no no gaps. */ + const int lowfd = open_multiple_temp_files (); + + const int maximum_fd = lowfd + NFDS; + const int half_fd = lowfd + NFDS / 2; + const int gap_1 = maximum_fd - 8; + + /* Close half of the descriptors and check result. */ + int r = close_range (lowfd, half_fd, CLOSE_RANGE_CLOEXEC); + if (r == -1 && errno == EINVAL) + { + printf ("%s: CLOSE_RANGE_CLOEXEC not supported\n", __func__); + return; + } + for (int i = lowfd; i <= half_fd; i++) + { + int flags = fcntl (i, F_GETFD); + TEST_VERIFY (flags > -1); + TEST_COMPARE (flags & FD_CLOEXEC, FD_CLOEXEC); + } + for (int i = half_fd + 1; i < maximum_fd; i++) + TEST_VERIFY (fcntl (i, F_GETFL) > -1); + + /* Create some gaps, close up to a threshold, and check result. */ + static int gap_close[] = { 57, 78, 81, 82, 84, 90 }; + for (int i = 0; i < array_length (gap_close); i++) + xclose (gap_close[i]); + + TEST_COMPARE (close_range (half_fd + 1, gap_1, CLOSE_RANGE_CLOEXEC), 0); + for (int i = half_fd + 1; i < gap_1; i++) + { + int flags = fcntl (i, F_GETFD); + if (is_in_array (gap_close, array_length (gap_close), i)) + TEST_COMPARE (flags, -1); + else + { + TEST_VERIFY (flags > -1); + TEST_COMPARE (flags & FD_CLOEXEC, FD_CLOEXEC); + } + } + for (int i = gap_1 + 1; i < maximum_fd; i++) + TEST_VERIFY (fcntl (i, F_GETFL) > -1); + + /* Close the remaining but the last one. */ + TEST_COMPARE (close_range (gap_1 + 1, maximum_fd - 1, CLOSE_RANGE_CLOEXEC), + 0); + for (int i = gap_1 + 1; i < maximum_fd - 1; i++) + { + int flags = fcntl (i, F_GETFD); + TEST_VERIFY (flags > -1); + TEST_COMPARE (flags & FD_CLOEXEC, FD_CLOEXEC); + } + TEST_VERIFY (fcntl (maximum_fd, F_GETFL) > -1); + + /* Close the last one. */ + TEST_COMPARE (close_range (maximum_fd, maximum_fd, CLOSE_RANGE_CLOEXEC), 0); + { + int flags = fcntl (maximum_fd, F_GETFD); + TEST_VERIFY (flags > -1); + TEST_COMPARE (flags & FD_CLOEXEC, FD_CLOEXEC); + } +} + +static int +do_test (void) +{ + close_range_test_max_upper_limit (); + close_range_test (); + close_range_test_subprocess (); + close_range_unshare_test (); + close_range_cloexec_test (); + + return 0; +} + +#include diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 57c4f28d17..e12670c1a4 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2325,6 +2325,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 47211abe4e..9b524d7b72 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2424,6 +2424,7 @@ GLIBC_2.34 aio_suspend64 F GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F +GLIBC_2.34 close_range F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F From patchwork Tue Jul 6 14:58:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44176 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A55B9388E825 for ; Tue, 6 Jul 2021 15:13:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A55B9388E825 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1625584397; bh=zRRl/KeRrgK9FKFzGg+4ZIA/UUG6tqBku6liQ9iWvbU=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Oh912J1I3iUfn7KJKcnKQL51FJFZdCaC5qDCiAbB/434M6YklulFxKK5qA2DfBd64 tEBLEf5xpMJwTYOcitIQGX20pBlNnYoBmUcvDN3oW3ewmJVmGxlGEESBlbp6LSyk3+ dsV/kc8DUIu+fXK/O0gsT92fcHE5kJ/zO+jqJFFs= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by sourceware.org (Postfix) with ESMTPS id 3BBDA388E83C for ; Tue, 6 Jul 2021 14:58:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3BBDA388E83C Received: by mail-pf1-x42d.google.com with SMTP id y2so6574257pff.11 for ; Tue, 06 Jul 2021 07:58:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zRRl/KeRrgK9FKFzGg+4ZIA/UUG6tqBku6liQ9iWvbU=; b=un1lpaFo6DXLq7F+iW/nvoJs4gShYJ9kgNjwPxG/h+XKQ3RRRzcpXNXlx7QBjPJd8l m0hF1qlRWS6DXaSc2Isl7AVSADyhd4A8akkDfepgxJ2Ha9NZ3dFHIz4+qjn0zRGJfFN8 EdvrYLtfqe4u15cJ9RDIR32vZxhSiSuXlgjS1YwPd4zsXGZ/V51zVvK34deWKghMCSOL Fr7pKHrxJXb40zkI0zRq+KRUCZUZRFLtHVCSFEDRM/JnQ/4NRCybBRIlQgA5TcEKNFb2 wp+fw4vBdO6mUEg7N4QOq8oR1noxXOZ5xM9xFNqq8Aru6MASI/uVms+jq4wO28apivpA Tq2w== X-Gm-Message-State: AOAM53162ZkwZfdA2WwMxngLIYh6f4aQsiQ0vjezz81KK9sLyImOeOmA 6Wj4FiUdvwr0y3AQLxRljRLzxG2bypDw+w== X-Google-Smtp-Source: ABdhPJxQ2ceps2oOI4axIN0JCUa4EnojXq7AQWrzLoTOvWP4kLgW02sWQrPNrE65FIZxArJcxgreKA== X-Received: by 2002:a63:1542:: with SMTP id 2mr21318856pgv.329.1625583528914; Tue, 06 Jul 2021 07:58:48 -0700 (PDT) Received: from birita.. ([177.194.59.218]) by smtp.gmail.com with ESMTPSA id n23sm19018488pgv.76.2021.07.06.07.58.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jul 2021 07:58:48 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v7 3/4] io: Add closefrom [BZ #10353] Date: Tue, 6 Jul 2021 11:58:38 -0300 Message-Id: <20210706145839.1658623-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210706145839.1658623-1-adhemerval.zanella@linaro.org> References: <20210706145839.1658623-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_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The function closes all open file descriptors greater than or equal to input argument. Negative values are clamped to 0, i.e, it will close all file descriptors. As indicated by the bug report, this is a common symbol provided by different systems (Solaris, OpenBSD, NetBSD, FreeBSD) and, although its has inherent issues with not taking in consideration internal libc file descriptors (such as syslog), this is also a common feature used in multiple projects [1][2][3][4][5]. The Linux fallback implementation iterates over /proc and close all file descriptors sequentially. Although it was raised the questioning whether getdents on /proc/self/fd might return disjointed entries when file descriptor are closed; it does not seems the case on my testing on multiple kernel (v4.18, v5.4, v5.9) and the same strategy is used on different projects [1][2][3][5]. Also, the interface is set a fail-safe meaning that a failure in the fallback results in a process abort. Checked on x86_64-linux-gnu on kernel v5.11 and v5.4. [1] https://github.com/systemd/systemd/blob/5238e9575906297608ff802a27e2ff9effa3b338/src/basic/fd-util.c#L217 [2] https://github.com/lxc/lxc/blob/ddf4b77e11a4d08f09b7b9cd13e593f8c047edc5/src/lxc/start.c#L236 [3] https://github.com/python/cpython/blob/9e4f2f3a6b8ee995c365e86d976937c141d867f8/Modules/_posixsubprocess.c#L220 [4] https://github.com/rust-lang/rust/blob/5f47c0613ed4eb46fca3633c1297364c09e5e451/src/libstd/sys/unix/process2.rs#L303-L308 [5] https://github.com/openjdk/jdk/blob/master/src/java.base/unix/native/libjava/childproc.c#L82 --- NEWS | 4 + include/unistd.h | 1 + io/Makefile | 4 +- io/Versions | 3 + io/closefrom.c | 34 ++++ io/tst-closefrom.c | 152 ++++++++++++++++++ manual/llio.texi | 10 ++ posix/unistd.h | 6 + sysdeps/mach/hurd/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/Makefile | 3 +- sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/closefrom.c | 35 ++++ sysdeps/unix/sysv/linux/closefrom_fallback.c | 97 +++++++++++ sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 44 files changed, 380 insertions(+), 2 deletions(-) create mode 100644 io/closefrom.c create mode 100644 io/tst-closefrom.c create mode 100644 sysdeps/unix/sysv/linux/closefrom.c create mode 100644 sysdeps/unix/sysv/linux/closefrom_fallback.c diff --git a/NEWS b/NEWS index be04b217fe..e01a245ac5 100644 --- a/NEWS +++ b/NEWS @@ -63,6 +63,10 @@ Major new features: * On Linux, the close_range function has been added. It allows efficiently closing a range of file descriptors on recent kernels (version 5.9). +* The function closefrom has been added. It closes all file descriptors + greater than given integer. This function is a GNU extension, although it + also present in other systems. + Deprecated and removed features, and other changes affecting compatibility: * The function pthread_mutex_consistent_np has been deprecated; programs diff --git a/include/unistd.h b/include/unistd.h index 691405a945..114a43128e 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -158,6 +158,7 @@ extern int __brk (void *__addr) attribute_hidden; extern int __close (int __fd); libc_hidden_proto (__close) extern int __libc_close (int __fd); +extern _Bool __closefrom_fallback (int __lowfd) attribute_hidden; extern ssize_t __read (int __fd, void *__buf, size_t __nbytes); libc_hidden_proto (__read) extern ssize_t __write (int __fd, const void *__buf, size_t __n); diff --git a/io/Makefile b/io/Makefile index 1a16990205..ebb7d56d67 100644 --- a/io/Makefile +++ b/io/Makefile @@ -56,7 +56,8 @@ routines := \ sendfile sendfile64 copy_file_range \ utimensat futimens file_change_detection \ fts64-time64 \ - ftw64-time64 + ftw64-time64 \ + closefrom others := pwd test-srcs := ftwtest ftwtest-time64 @@ -77,6 +78,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ tst-lutimes \ tst-futimens \ tst-utimensat \ + tst-closefrom \ tests-time64 := \ tst-futimens-time64 \ diff --git a/io/Versions b/io/Versions index 88caf76bbc..4e19540885 100644 --- a/io/Versions +++ b/io/Versions @@ -137,6 +137,9 @@ libc { stat; stat64; fstat; fstat64; lstat; lstat64; fstatat; fstatat64; mknod; mknodat; } + GLIBC_2.34 { + closefrom; + } GLIBC_PRIVATE { __libc_fcntl64; __fcntl_nocancel; diff --git a/io/closefrom.c b/io/closefrom.c new file mode 100644 index 0000000000..01660a7531 --- /dev/null +++ b/io/closefrom.c @@ -0,0 +1,34 @@ +/* Close a range of file descriptors. + Copyright (C) 2021 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 + +void +__closefrom (int lowfd) +{ + int maxfd = __getdtablesize (); + if (maxfd == -1) + __fortify_fail ("closefrom failed to get the file descriptor table size"); + + for (int i = 0; i < maxfd; i++) + if (i >= lowfd) + __close_nocancel_nostatus (i); +} +weak_alias (__closefrom, closefrom) diff --git a/io/tst-closefrom.c b/io/tst-closefrom.c new file mode 100644 index 0000000000..d4c187073c --- /dev/null +++ b/io/tst-closefrom.c @@ -0,0 +1,152 @@ +/* Smoke test for the closefrom. + Copyright (C) 2021 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 + +#define NFDS 100 + +static int +open_multiple_temp_files (void) +{ + /* Check if the temporary file descriptor has no no gaps. */ + int lowfd = xopen ("/dev/null", O_RDONLY, 0600); + for (int i = 1; i <= NFDS; i++) + TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), lowfd + i); + return lowfd; +} + +static int +closefrom_test (void) +{ + struct support_descriptors *descrs = support_descriptors_list (); + + int lowfd = open_multiple_temp_files (); + + const int maximum_fd = lowfd + NFDS; + const int half_fd = lowfd + NFDS / 2; + const int gap = maximum_fd / 4; + + /* Close half of the descriptors and check result. */ + closefrom (half_fd); + + for (int i = half_fd; i <= maximum_fd; i++) + { + TEST_COMPARE (fcntl (i, F_GETFL), -1); + TEST_COMPARE (errno, EBADF); + } + for (int i = 0; i < half_fd; i++) + TEST_VERIFY (fcntl (i, F_GETFL) > -1); + + /* Create some gaps, close up to a threshold, and check result. */ + xclose (lowfd + 35); + xclose (lowfd + 38); + xclose (lowfd + 42); + xclose (lowfd + 46); + + /* Close half of the descriptors and check result. */ + closefrom (gap); + for (int i = gap + 1; i < maximum_fd; i++) + { + TEST_COMPARE (fcntl (i, F_GETFL), -1); + TEST_COMPARE (errno, EBADF); + } + for (int i = 0; i < gap; i++) + TEST_VERIFY (fcntl (i, F_GETFL) > -1); + + /* Close the remmaining but the last one. */ + closefrom (lowfd + 1); + for (int i = lowfd + 1; i <= maximum_fd; i++) + { + TEST_COMPARE (fcntl (i, F_GETFL), -1); + TEST_COMPARE (errno, EBADF); + } + TEST_VERIFY (fcntl (lowfd, F_GETFL) > -1); + + /* Close the last one. */ + closefrom (lowfd); + TEST_COMPARE (fcntl (lowfd, F_GETFL), -1); + TEST_COMPARE (errno, EBADF); + + /* Double check by check the /proc. */ + support_descriptors_check (descrs); + support_descriptors_free (descrs); + + return 0; +} + +/* Check if closefrom works even when no new file descriptors can be + created. */ +static int +closefrom_test_file_desc_limit (void) +{ + int max_fd = NFDS; + { + struct rlimit rl; + if (getrlimit (RLIMIT_NOFILE, &rl) == -1) + FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m"); + + max_fd = (rl.rlim_cur < max_fd ? rl.rlim_cur : max_fd); + rl.rlim_cur = max_fd; + + if (setrlimit (RLIMIT_NOFILE, &rl) == 1) + FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m"); + } + + /* Exhauste the file descriptor limit. */ + int lowfd = xopen ("/dev/null", O_RDONLY, 0600); + for (;;) + { + int fd = open ("/dev/null", O_RDONLY, 0600); + if (fd == -1) + { + if (errno != EMFILE) + FAIL_EXIT1 ("open: %m"); + break; + } + TEST_VERIFY_EXIT (fd < max_fd); + } + + closefrom (lowfd); + for (int i = lowfd; i < NFDS; i++) + { + TEST_COMPARE (fcntl (i, F_GETFL), -1); + TEST_COMPARE (errno, EBADF); + } + + return 0; +} + +static int +do_test (void) +{ + closefrom_test (); + closefrom_test_file_desc_limit (); + + return 0; +} + +#include diff --git a/manual/llio.texi b/manual/llio.texi index ea6d34dd5a..d1ed9e6490 100644 --- a/manual/llio.texi +++ b/manual/llio.texi @@ -332,6 +332,16 @@ The kernel does not implement the required functionality. @end table @end deftypefun +@deftypefun void closefrom (int @var{lowfd}) +@standards{GNU, unistd.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} + +The function @code{closefrom} closes all file descriptors larger than or equal +to @var{lowfd} then @var{lowfd}. This function is similar to call +@code{close} applied to the specified file descriptor range. + +Already closed file descriptors are ignored. +@end deftypefun @node I/O Primitives @section Input and Output Primitives diff --git a/posix/unistd.h b/posix/unistd.h index 217c6c5363..3dca65732f 100644 --- a/posix/unistd.h +++ b/posix/unistd.h @@ -357,6 +357,12 @@ extern __off64_t lseek64 (int __fd, __off64_t __offset, int __whence) __THROW. */ extern int close (int __fd); +#ifdef __USE_MISC +/* Close all open file descriptors greater than or equal to LOWFD. + Negative LOWFD is clamped to 0. */ +extern void closefrom (int __lowfd) __THROW; +#endif + /* Read NBYTES into BUF from FD. Return the number read, -1 for errors or 0 for EOF. diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index fcfe64f26b..475bf2d6e9 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2225,6 +2225,7 @@ GLIBC_2.34 _Fork F GLIBC_2.34 __isnanf128 F GLIBC_2.34 __libc_start_main F GLIBC_2.34 _hurd_libc_proc_init F +GLIBC_2.34 closefrom F GLIBC_2.34 dladdr F GLIBC_2.34 dladdr1 F GLIBC_2.34 dlclose F diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index e308711168..d45a16af8b 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -64,7 +64,8 @@ sysdep_routines += adjtimex clone umount umount2 readahead sysctl \ pselect32 \ xstat fxstat lxstat xstat64 fxstat64 lxstat64 \ fxstatat fxstatat64 \ - xmknod xmknodat convert_scm_timestamps + xmknod xmknodat convert_scm_timestamps \ + closefrom_fallback CFLAGS-gethostid.c = -fexceptions CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index c32f5898fe..5f6c9768c5 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2410,6 +2410,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index cb10eadbb9..5fcf38ad44 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2509,6 +2509,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index a697c930e1..0903ec5b27 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2169,6 +2169,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 7dbe38dcb7..38f56b13a7 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -303,6 +303,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index 0ee69506ea..3b8522f297 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -300,6 +300,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/closefrom.c b/sysdeps/unix/sysv/linux/closefrom.c new file mode 100644 index 0000000000..f5d7342c2c --- /dev/null +++ b/sysdeps/unix/sysv/linux/closefrom.c @@ -0,0 +1,35 @@ +/* Close a range of file descriptors. Linux version. + Copyright (C) 2021 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 + +void +__closefrom (int lowfd) +{ + int l = MAX (0, lowfd); + + int r = __close_range (l, ~0U, 0); + if (r == 0) + return; + + if (!__closefrom_fallback (l)) + __fortify_fail ("closefrom failed to close a file descriptor"); +} +weak_alias (__closefrom, closefrom) diff --git a/sysdeps/unix/sysv/linux/closefrom_fallback.c b/sysdeps/unix/sysv/linux/closefrom_fallback.c new file mode 100644 index 0000000000..61e71d388d --- /dev/null +++ b/sysdeps/unix/sysv/linux/closefrom_fallback.c @@ -0,0 +1,97 @@ +/* Close a range of file descriptors. Linux version. + Copyright (C) 2021 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 + +/* Fallback code: iterates over /proc/self/fd, closing each file descriptor + that fall on the criteria. */ +_Bool +__closefrom_fallback (int from) +{ + bool ret = false; + + int dirfd = __open_nocancel (FD_TO_FILENAME_PREFIX, O_RDONLY | O_DIRECTORY, + 0); + if (dirfd == -1) + { + /* The closefrom should work even when process can't open new files. */ + if (errno == ENOENT) + goto err; + + for (int i = from; i < INT_MAX; i++) + { + int r = __close_nocancel (i); + if (r == 0 || (r == -1 && errno != EBADF)) + break; + } + + dirfd = __open_nocancel (FD_TO_FILENAME_PREFIX, O_RDONLY | O_DIRECTORY, + 0); + if (dirfd == -1) + goto err; + } + + char buffer[1024]; + while (true) + { + ssize_t ret = __getdents64 (dirfd, buffer, sizeof (buffer)); + if (ret == -1) + goto err; + else if (ret == 0) + break; + + /* If any file descriptor is closed it resets the /proc/self position + read again from the start (to obtain any possible kernel update). */ + bool closed = false; + char *begin = buffer, *end = buffer + ret; + while (begin != end) + { + unsigned short int d_reclen; + memcpy (&d_reclen, begin + offsetof (struct dirent64, d_reclen), + sizeof (d_reclen)); + const char *dname = begin + offsetof (struct dirent64, d_name); + begin += d_reclen; + + if (dname[0] == '.') + continue; + + int fd = 0; + for (const char *s = dname; (unsigned int) (*s) - '0' < 10; s++) + fd = 10 * fd + (*s - '0'); + + if (fd == dirfd || fd < from) + continue; + + /* We ignore close errors because EBADF, EINTR, and EIO means the + descriptor has been released. */ + __close_nocancel (fd); + closed = true; + } + + if (closed && __lseek (dirfd, 0, SEEK_SET) < 0) + goto err; + } + + ret = true; +err: + __close_nocancel (dirfd); + return ret; +} diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index c5849e1da2..0552d47461 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2435,6 +2435,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 9368379d9d..ed3defc560 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2388,6 +2388,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index e4a16d0bcf..ad59582311 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2572,6 +2572,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index f7a29d00de..2b54a7abec 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2347,6 +2347,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 7a1b38fe81..3089cd413a 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -304,6 +304,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 64591d99cc..d1714c6adc 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2515,6 +2515,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 1769dc5c80..66e19a4c27 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2486,6 +2486,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 4373d181fb..7ffe575d6b 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2483,6 +2483,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index c714662ff3..b1e177971a 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2480,6 +2480,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index d6d9f3b5f6..bbb5849961 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2478,6 +2478,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 287fc03201..cfd0d2733b 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2486,6 +2486,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 92dc711ee2..79bcb1bedb 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2398,6 +2398,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index b1c4e54a70..54048ea725 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2525,6 +2525,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 1ed9e1c9a7..300c1a187e 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2542,6 +2542,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index 953e05cc33..7f00f9ec7c 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2575,6 +2575,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index e6bcab06d5..26fd4762ad 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2311,6 +2311,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 525cb85de2..02581f12cc 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2606,6 +2606,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index a1d89d2f14..6f01f5df0d 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2171,6 +2171,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 84f7a8561a..d69e1589b7 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2371,6 +2371,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index edd1dbbbdb..b9440770af 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2540,6 +2540,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 19160f33ba..274c743a2a 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2348,6 +2348,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 8e99b18060..42138cba69 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2395,6 +2395,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index f876e152b7..57f7df559c 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2392,6 +2392,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index a6fa1a1b29..1929d5801d 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2535,6 +2535,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 4f6166a8f1..8fe2d5a9d9 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2370,6 +2370,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index e12670c1a4..3412dcaf69 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2326,6 +2326,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 9b524d7b72..04d540e619 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2425,6 +2425,7 @@ GLIBC_2.34 aio_write F GLIBC_2.34 aio_write64 F GLIBC_2.34 call_once F GLIBC_2.34 close_range F +GLIBC_2.34 closefrom F GLIBC_2.34 cnd_broadcast F GLIBC_2.34 cnd_destroy F GLIBC_2.34 cnd_init F From patchwork Tue Jul 6 14:58:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44177 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7C661388E834 for ; Tue, 6 Jul 2021 15:14:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7C661388E834 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1625584448; bh=Lf4qoTn3ZPgHmuigq8I06HR3StjRIY1xN9UkrV8+Zr8=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Cq3rPt2Fix86wNxtBIwTNGxLV7i+B8SYlT5w+jgsrvnbqmYVTgquCf9YiY4qPtw1F nxjqN/wfhjzJ1tuIRKp4IXh1s6ppifqNKF9ib5/Vx3t1metkgegJM6Sh3mIrlhT9Ly SpKolMKOK8ZsN6ZUm7RjNbD12zpaEmdeK+xZy6FM= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by sourceware.org (Postfix) with ESMTPS id 1BFD1388E82F for ; Tue, 6 Jul 2021 14:58:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1BFD1388E82F Received: by mail-pg1-x52f.google.com with SMTP id 62so13549965pgf.1 for ; Tue, 06 Jul 2021 07:58:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Lf4qoTn3ZPgHmuigq8I06HR3StjRIY1xN9UkrV8+Zr8=; b=tT307CNxvRA2tszRrGd0mzjfrGY0kCp36q5aWiRSNlIie/RAqNlnFYF+fKUR6yzYD+ a1/RN5ak0HEJpmqFOQ5a/bzXNhKc9ftTo6oZPBt2/qKK1MvfKjWGqgcq/DQoPKqEarhx 4BPAnNq5Si6uMi+5jE5WJMqWdDwUMRLmbo4bFweWgn823/5HuOZUSaRC0fUIuBPLbnZk sl87NtIocEES7t9jpUvVDggG0X490dBQJK7b2hBjRn8NGFGnVwTjlIwtmetobgTRqrF7 khibYJlA38ZbXtmoGbiPFFXwM+wBo5h0IKe7c92OrHNVQo1P56YW8U0tnR+clrzPgU9g +0Xw== X-Gm-Message-State: AOAM530gksLKfTe9DBzqAw9oLBWr0K5drZbJvDJpUovO8qMfwybhfojZ uuNnDxp/k+WFLv3cOiaN7AtI6yxOJySdwg== X-Google-Smtp-Source: ABdhPJxmL3p0qkfXXPHcqc0ysySrAEssQj9xOF4J2nhG5x5RpY3bRdyZP7fniJUuoTo5cVqt3dZTiQ== X-Received: by 2002:a63:f108:: with SMTP id f8mr21347578pgi.109.1625583530370; Tue, 06 Jul 2021 07:58:50 -0700 (PDT) Received: from birita.. ([177.194.59.218]) by smtp.gmail.com with ESMTPSA id n23sm19018488pgv.76.2021.07.06.07.58.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jul 2021 07:58:50 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v7 4/4] posix: Add posix_spawn_file_actions_addclosefrom_np Date: Tue, 6 Jul 2021 11:58:39 -0300 Message-Id: <20210706145839.1658623-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210706145839.1658623-1-adhemerval.zanella@linaro.org> References: <20210706145839.1658623-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_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This patch adds a way to close a range of file descriptors on posix_spawn as a new file action. The API is similar to the one provided by Solaris 11 [1], where the file action causes the all open file descriptors greater than or equal to input on to be closed when the new process is spawned. The function posix_spawn_file_actions_addclosefrom_np is safe to be implemented by iterating over /proc/self/fd, since the Linux spawni.c helper process does not use CLONE_FILES, so its has own file descriptor table and any failure (in /proc operation) aborts the process creation and returns an error to the caller. I am aware that this file action might be redundant to the current approach of POSIX in promoting O_CLOEXEC in more interfaces. However O_CLOEXEC is still not the default and for some specific usages, the caller needs to close all possible file descriptors to avoid them leaking. Some examples are CPython (discussed in BZ#10353) and OpenJDK jspawnhelper [2] (where OpenJDK spawns a helper process to exactly closes all file descriptors). Most likely any environment which calls functions that might open file descriptor under the hood and aim to use posix_spawn might face the same requirement. Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu, and aarch64-linux-gnu. [1] https://docs.oracle.com/cd/E36784_01/html/E36874/posix-spawn-file-actions-addclosefrom-np-3c.html [2] https://github.com/openjdk/jdk/blob/master/src/java.base/unix/native/libjava/childproc.c#L82 --- NEWS | 5 + include/unistd.h | 2 +- posix/Makefile | 4 +- posix/Versions | 1 + posix/spawn.h | 8 + posix/spawn_faction_addclosefrom.c | 57 ++++ posix/spawn_faction_destroy.c | 1 + posix/spawn_int.h | 6 + posix/tst-spawn5.c | 284 ++++++++++++++++++ sysdeps/generic/spawn_int_def.h | 24 ++ sysdeps/mach/hurd/i386/libc.abilist | 1 + sysdeps/mach/hurd/spawni.c | 4 + sysdeps/posix/spawni.c | 4 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/closefrom.c | 3 +- sysdeps/unix/sysv/linux/closefrom_fallback.c | 8 +- sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + sysdeps/unix/sysv/linux/spawn_int_def.h | 25 ++ sysdeps/unix/sysv/linux/spawni.c | 34 ++- .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 49 files changed, 482 insertions(+), 21 deletions(-) create mode 100644 posix/spawn_faction_addclosefrom.c create mode 100644 posix/tst-spawn5.c create mode 100644 sysdeps/generic/spawn_int_def.h create mode 100644 sysdeps/unix/sysv/linux/spawn_int_def.h diff --git a/NEWS b/NEWS index e01a245ac5..91d5f17598 100644 --- a/NEWS +++ b/NEWS @@ -67,6 +67,11 @@ Major new features: greater than given integer. This function is a GNU extension, although it also present in other systems. +* The posix_spawn_file_actions_closefrom_np function has been added, enabling + posix_spawn and posix_spawnp to close all file descriptors great than or + equal to a giver integer. This function is a GNU extension, although + Solaris also provides a similar function. + Deprecated and removed features, and other changes affecting compatibility: * The function pthread_mutex_consistent_np has been deprecated; programs diff --git a/include/unistd.h b/include/unistd.h index 114a43128e..7849562c42 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -158,7 +158,7 @@ extern int __brk (void *__addr) attribute_hidden; extern int __close (int __fd); libc_hidden_proto (__close) extern int __libc_close (int __fd); -extern _Bool __closefrom_fallback (int __lowfd) attribute_hidden; +extern _Bool __closefrom_fallback (int __lowfd, _Bool) attribute_hidden; extern ssize_t __read (int __fd, void *__buf, size_t __nbytes); libc_hidden_proto (__read) extern ssize_t __write (int __fd, const void *__buf, size_t __n); diff --git a/posix/Makefile b/posix/Makefile index e91ea25ba1..d82e43eaad 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -57,6 +57,7 @@ routines := \ spawn_faction_init spawn_faction_destroy spawn_faction_addclose \ spawn_faction_addopen spawn_faction_adddup2 spawn_valid_fd \ spawn_faction_addchdir spawn_faction_addfchdir \ + spawn_faction_addclosefrom \ spawnattr_init spawnattr_destroy \ spawnattr_getdefault spawnattr_setdefault \ spawnattr_getflags spawnattr_setflags \ @@ -106,7 +107,7 @@ tests := test-errno tstgetopt testfnm runtests runptests \ tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \ tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \ bug-regex38 tst-regcomp-truncated tst-spawn-chdir \ - tst-wordexp-nocmd tst-execveat + tst-wordexp-nocmd tst-execveat tst-spawn5 # Test for the glob symbol version that was replaced in glibc 2.27. ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes) @@ -276,6 +277,7 @@ tst-exec-static-ARGS = $(tst-exec-ARGS) tst-execvpe5-ARGS = -- $(host-test-program-cmd) tst-spawn-ARGS = -- $(host-test-program-cmd) tst-spawn-static-ARGS = $(tst-spawn-ARGS) +tst-spawn5-ARGS = -- $(host-test-program-cmd) tst-dir-ARGS = `pwd` `cd $(common-objdir)/$(subdir); pwd` `cd $(common-objdir); pwd` $(objpfx)tst-dir tst-chmod-ARGS = $(objdir) tst-vfork3-ARGS = --test-dir=$(objpfx) diff --git a/posix/Versions b/posix/Versions index ee1f412185..a78792135f 100644 --- a/posix/Versions +++ b/posix/Versions @@ -154,6 +154,7 @@ libc { GLIBC_2.34 { _Fork; execveat; + posix_spawn_file_actions_addclosefrom_np; } GLIBC_PRIVATE { __libc_fork; __libc_pread; __libc_pwrite; diff --git a/posix/spawn.h b/posix/spawn.h index a29da028cc..990d8a6ba2 100644 --- a/posix/spawn.h +++ b/posix/spawn.h @@ -213,6 +213,14 @@ extern int posix_spawn_file_actions_addchdir_np (posix_spawn_file_actions_t * extern int posix_spawn_file_actions_addfchdir_np (posix_spawn_file_actions_t *, int __fd) __THROW __nonnull ((1)); + +/* Add an action to close all file descriptor greater than or equal to FROM + during spawn. This affects the subsequent file actions. */ +extern int +posix_spawn_file_actions_addclosefrom_np (posix_spawn_file_actions_t *, + int __from) + __THROW __nonnull ((1)); + #endif __END_DECLS diff --git a/posix/spawn_faction_addclosefrom.c b/posix/spawn_faction_addclosefrom.c new file mode 100644 index 0000000000..ff35b0519b --- /dev/null +++ b/posix/spawn_faction_addclosefrom.c @@ -0,0 +1,57 @@ +/* Add a closefrom to a file action list for posix_spawn. + Copyright (C) 2021 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 + +int +__posix_spawn_file_actions_addclosefrom (posix_spawn_file_actions_t + *file_actions, int from) +{ +#if __SPAWN_SUPPORT_CLOSEFROM + struct __spawn_action *rec; + + if (!__spawn_valid_fd (from)) + return EBADF; + + /* Allocate more memory if needed. */ + if (file_actions->__used == file_actions->__allocated + && __posix_spawn_file_actions_realloc (file_actions) != 0) + /* This can only mean we ran out of memory. */ + return ENOMEM; + + /* Add the new value. */ + rec = &file_actions->__actions[file_actions->__used]; + rec->tag = spawn_do_closefrom; + rec->action.closefrom_action.from = from; + + /* Account for the new entry. */ + ++file_actions->__used; + + return 0; +#else + return EINVAL; +#endif +} +weak_alias (__posix_spawn_file_actions_addclosefrom, + posix_spawn_file_actions_addclosefrom_np) +#if !__SPAWN_SUPPORT_CLOSEFROM +stub_warning (posix_spawn_file_actions_addclosefrom_np) +#endif diff --git a/posix/spawn_faction_destroy.c b/posix/spawn_faction_destroy.c index 7776f1a462..1a01b8e80e 100644 --- a/posix/spawn_faction_destroy.c +++ b/posix/spawn_faction_destroy.c @@ -39,6 +39,7 @@ __posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions) case spawn_do_close: case spawn_do_dup2: case spawn_do_fchdir: + case spawn_do_closefrom: /* No cleanup required. */ break; } diff --git a/posix/spawn_int.h b/posix/spawn_int.h index c579cb981d..81d43f2fa3 100644 --- a/posix/spawn_int.h +++ b/posix/spawn_int.h @@ -20,6 +20,7 @@ #define _SPAWN_INT_H #include +#include #include /* Data structure to contain the action information. */ @@ -32,6 +33,7 @@ struct __spawn_action spawn_do_open, spawn_do_chdir, spawn_do_fchdir, + spawn_do_closefrom, } tag; union @@ -60,6 +62,10 @@ struct __spawn_action { int fd; } fchdir_action; + struct + { + int from; + } closefrom_action; } action; }; diff --git a/posix/tst-spawn5.c b/posix/tst-spawn5.c new file mode 100644 index 0000000000..1e67d071b4 --- /dev/null +++ b/posix/tst-spawn5.c @@ -0,0 +1,284 @@ +/* Tests for posix_spawn signal handling. + Copyright (C) 2021 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 + +/* Nonzero if the program gets called via `exec'. */ +static int restart; + +/* Hold the four initial argument used to respawn the process, plus + the extra '--direct' and '--restart', and a final NULL. */ +static char *initial_argv[7]; + +#define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +#define NFDS 100 + +static int +open_multiple_temp_files (void) +{ + /* Check if the temporary file descriptor has no no gaps. */ + int lowfd = xopen ("/dev/null", O_RDONLY, 0600); + for (int i = 1; i <= NFDS; i++) + TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), + lowfd + i); + return lowfd; +} + +/* Called on process re-execution. The arguments are the expected opened + file descriptors. */ +_Noreturn static void +handle_restart (int argc, char *argv[]) +{ + size_t nfds = argc > 1 ? argc - 1 : 0; + struct fd_t + { + int fd; + _Bool found; + } *fds = xmalloc (sizeof (struct fd_t) * nfds); + for (int i = 0; i < nfds; i++) + { + char *endptr; + long unsigned int fd = strtoul (argv[i+1], &endptr, 10); + if (*endptr != '\0' || fd > INT_MAX) + FAIL_EXIT1 ("readdir: invalid file descriptor value: %s", argv[i]); + + fds[i].fd = fd; + fds[i].found = false; + } + + DIR *dirp = opendir (FD_TO_FILENAME_PREFIX); + if (dirp == NULL) + FAIL_EXIT1 ("opendir (\"" FD_TO_FILENAME_PREFIX "\"): %m"); + + while (true) + { + errno = 0; + struct dirent64 *e = readdir64 (dirp); + if (e == NULL) + { + if (errno != 0) + FAIL_EXIT1 ("readdir: %m"); + break; + } + + if (e->d_name[0] == '.') + continue; + + char *endptr; + long int fd = strtol (e->d_name, &endptr, 10); + if (*endptr != '\0' || fd < 0 || fd > INT_MAX) + FAIL_EXIT1 ("readdir: invalid file descriptor name: /proc/self/fd/%s", + e->d_name); + + /* Skip the descriptor which is used to enumerate the descriptors. */ + if (fd == dirfd (dirp) + || fd == STDIN_FILENO + || fd == STDOUT_FILENO + || fd == STDERR_FILENO) + continue; + + bool found = false; + for (int i = 0; i < nfds; i++) + if (fds[i].fd == fd) + fds[i].found = found = true; + + if (!found) + FAIL_EXIT1 ("unexpected open file descriptor: %ld", fd); + } + closedir (dirp); + + for (int i = 0; i < nfds; i++) + if (!fds[i].found) + FAIL_EXIT1 ("file descriptor %d not opened", fds[i].fd); + + free (fds); + + exit (EXIT_SUCCESS); +} + +static void +spawn_closefrom_test (posix_spawn_file_actions_t *fa, int lowfd, int highfd, + int *extrafds, size_t nextrafds) +{ + /* 6 elements from initial_argv (path to ld.so, '--library-path', the + path', application name', '--direct', and '--restart'), up to + 2 * maximum_fd arguments (the expected open file descriptors), plus + NULL. */ + enum { argv_size = array_length (initial_argv) + 2 * NFDS + 1 }; + char *args[argv_size]; + int argc = 0; + + for (char **arg = initial_argv; *arg != NULL; arg++) + args[argc++] = *arg; + + for (int i = lowfd; i < highfd; i++) + args[argc++] = xasprintf ("%d", i); + + for (int i = 0; i < nextrafds; i++) + args[argc++] = xasprintf ("%d", extrafds[i]); + + args[argc] = NULL; + TEST_VERIFY (argc < argv_size); + + pid_t pid; + int status; + + TEST_COMPARE (posix_spawn (&pid, args[0], fa, NULL, args, environ), 0); + TEST_COMPARE (xwaitpid (pid, &status, 0), pid); + TEST_VERIFY (WIFEXITED (status)); + TEST_VERIFY (!WIFSIGNALED (status)); + TEST_COMPARE (WEXITSTATUS (status), 0); +} + +static void +do_test_closefrom (void) +{ + int lowfd = open_multiple_temp_files (); + const int half_fd = lowfd + NFDS / 2; + + /* Close half of the descriptors and check result. */ + { + posix_spawn_file_actions_t fa; + TEST_COMPARE (posix_spawn_file_actions_init (&fa), 0); + + int ret = posix_spawn_file_actions_addclosefrom_np (&fa, half_fd); + if (ret == EINVAL) + /* Hurd currently does not support closefrom fileaction. */ + FAIL_UNSUPPORTED ("posix_spawn_file_actions_addclosefrom_np unsupported"); + TEST_COMPARE (ret, 0); + + spawn_closefrom_test (&fa, lowfd, half_fd, NULL, 0); + + TEST_COMPARE (posix_spawn_file_actions_destroy (&fa), 0); + } + + /* Create some gaps, close up to a threshold, and check result. */ + xclose (lowfd + 57); + xclose (lowfd + 78); + xclose (lowfd + 81); + xclose (lowfd + 82); + xclose (lowfd + 84); + xclose (lowfd + 90); + + { + posix_spawn_file_actions_t fa; + TEST_COMPARE (posix_spawn_file_actions_init (&fa), 0); + + TEST_COMPARE (posix_spawn_file_actions_addclosefrom_np (&fa, half_fd), 0); + + spawn_closefrom_test (&fa, lowfd, half_fd, NULL, 0); + + TEST_COMPARE (posix_spawn_file_actions_destroy (&fa), 0); + } + + /* Close the remaining but the last one. */ + { + posix_spawn_file_actions_t fa; + TEST_COMPARE (posix_spawn_file_actions_init (&fa), 0); + + TEST_COMPARE (posix_spawn_file_actions_addclosefrom_np (&fa, lowfd + 1), 0); + + spawn_closefrom_test (&fa, lowfd, lowfd + 1, NULL, 0); + + TEST_COMPARE (posix_spawn_file_actions_destroy (&fa), 0); + } + + /* Close everything. */ + { + posix_spawn_file_actions_t fa; + TEST_COMPARE (posix_spawn_file_actions_init (&fa), 0); + + TEST_COMPARE (posix_spawn_file_actions_addclosefrom_np (&fa, lowfd), 0); + + spawn_closefrom_test (&fa, lowfd, lowfd, NULL, 0); + + TEST_COMPARE (posix_spawn_file_actions_destroy (&fa), 0); + } + + /* Close a range and add some file actions. */ + { + posix_spawn_file_actions_t fa; + TEST_COMPARE (posix_spawn_file_actions_init (&fa), 0); + + TEST_COMPARE (posix_spawn_file_actions_addclosefrom_np (&fa, lowfd + 1), 0); + TEST_COMPARE (posix_spawn_file_actions_addopen (&fa, lowfd, "/dev/null", + 0666, O_RDONLY), 0); + TEST_COMPARE (posix_spawn_file_actions_adddup2 (&fa, lowfd, lowfd + 1), 0); + TEST_COMPARE (posix_spawn_file_actions_addopen (&fa, lowfd, "/dev/null", + 0666, O_RDONLY), 0); + + spawn_closefrom_test (&fa, lowfd, lowfd, (int[]){lowfd, lowfd + 1}, 2); + + TEST_COMPARE (posix_spawn_file_actions_destroy (&fa), 0); + } +} + +static int +do_test (int argc, char *argv[]) +{ + /* We must have either: + + - one or four parameters if called initially: + + argv[1]: path for ld.so optional + + argv[2]: "--library-path" optional + + argv[3]: the library path optional + + argv[4]: the application name + + - six parameters left if called through re-execution: + + argv[1]: the application name + + argv[2]: first expected open file descriptor + + argv[n]: last expected open file descritptor + + * When built with --enable-hardcoded-path-in-tests or issued without + using the loader directly. */ + + if (restart) + handle_restart (argc, argv); + + initial_argv[0] = argv[1]; /* path for ld.so */ + initial_argv[1] = argv[2]; /* "--library-path" */ + initial_argv[2] = argv[3]; /* the library path */ + initial_argv[3] = argv[4]; /* the application name */ + initial_argv[4] = (char *) "--direct"; + initial_argv[5] = (char *) "--restart"; + + do_test_closefrom (); + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include diff --git a/sysdeps/generic/spawn_int_def.h b/sysdeps/generic/spawn_int_def.h new file mode 100644 index 0000000000..ef6e03b1ef --- /dev/null +++ b/sysdeps/generic/spawn_int_def.h @@ -0,0 +1,24 @@ +/* Internal definitions for posix_spawn functionality. Generic version. + Copyright (C) 2021 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 _SPAWN_INT_DEF_H +#define _SPAWN_INT_DEF_H + +#define __SPAWN_SUPPORT_CLOSEFROM 0 + +#endif /* _SPAWN_INT_H */ diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index 475bf2d6e9..25003cda37 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2242,6 +2242,7 @@ GLIBC_2.34 login_tty F GLIBC_2.34 logout F GLIBC_2.34 logwtmp F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 shm_open F GLIBC_2.34 shm_unlink F GLIBC_2.34 timespec_getres F diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c index b5c92365f2..e011c3b34b 100644 --- a/sysdeps/mach/hurd/spawni.c +++ b/sysdeps/mach/hurd/spawni.c @@ -613,6 +613,10 @@ retry: case spawn_do_fchdir: err = child_fchdir (action->action.fchdir_action.fd); break; + + case spawn_do_closefrom: + err = EINVAL; + break; } if (err) diff --git a/sysdeps/posix/spawni.c b/sysdeps/posix/spawni.c index fe3b5bb7f6..ad1858fe4e 100644 --- a/sysdeps/posix/spawni.c +++ b/sysdeps/posix/spawni.c @@ -231,6 +231,10 @@ __spawni_child (void *arguments) if (__fchdir (action->action.fchdir_action.fd) != 0) goto fail; break; + + case spawn_do_closefrom: + __set_errno (EINVAL); + goto fail; } } } diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 5f6c9768c5..2fbdf6c6ef 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2455,6 +2455,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 5fcf38ad44..222275ea90 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2554,6 +2554,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index 0903ec5b27..b7aee90e15 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2214,6 +2214,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 38f56b13a7..47f13bbe33 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -348,6 +348,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index 3b8522f297..683d034b31 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -345,6 +345,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/closefrom.c b/sysdeps/unix/sysv/linux/closefrom.c index f5d7342c2c..372896b775 100644 --- a/sysdeps/unix/sysv/linux/closefrom.c +++ b/sysdeps/unix/sysv/linux/closefrom.c @@ -16,6 +16,7 @@ License along with the GNU C Library; if not, see . */ +#include #include #include #include @@ -29,7 +30,7 @@ __closefrom (int lowfd) if (r == 0) return; - if (!__closefrom_fallback (l)) + if (!__closefrom_fallback (l, true)) __fortify_fail ("closefrom failed to close a file descriptor"); } weak_alias (__closefrom, closefrom) diff --git a/sysdeps/unix/sysv/linux/closefrom_fallback.c b/sysdeps/unix/sysv/linux/closefrom_fallback.c index 61e71d388d..9cca55653a 100644 --- a/sysdeps/unix/sysv/linux/closefrom_fallback.c +++ b/sysdeps/unix/sysv/linux/closefrom_fallback.c @@ -22,9 +22,11 @@ #include /* Fallback code: iterates over /proc/self/fd, closing each file descriptor - that fall on the criteria. */ + that fall on the criteria. If DIRFD_FALLBACK is set, a failure on + /proc/self/fd open will trigger a fallback that tries to close a file + descriptor before proceed. */ _Bool -__closefrom_fallback (int from) +__closefrom_fallback (int from, _Bool dirfd_fallback) { bool ret = false; @@ -33,7 +35,7 @@ __closefrom_fallback (int from) if (dirfd == -1) { /* The closefrom should work even when process can't open new files. */ - if (errno == ENOENT) + if (errno == ENOENT || !dirfd_fallback) goto err; for (int i = from; i < INT_MAX; i++) diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 0552d47461..d416c180d7 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2480,6 +2480,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index ed3defc560..21747aa608 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2433,6 +2433,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index ad59582311..a06c8e0558 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2617,6 +2617,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 2b54a7abec..fbb15b365f 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2392,6 +2392,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 3089cd413a..29086b3707 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -349,6 +349,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index d1714c6adc..72a21d1c39 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2560,6 +2560,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 66e19a4c27..e8721049dc 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2531,6 +2531,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 7ffe575d6b..3abd242ef2 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2528,6 +2528,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index b1e177971a..dfa0cf7df3 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2525,6 +2525,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index bbb5849961..fbcaffc9ed 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2523,6 +2523,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index cfd0d2733b..2781e8fffb 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2531,6 +2531,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 79bcb1bedb..377b91d48a 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2443,6 +2443,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index 54048ea725..18977bddeb 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2570,6 +2570,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 300c1a187e..55bed75ba2 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2587,6 +2587,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index 7f00f9ec7c..acee98746c 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2620,6 +2620,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 26fd4762ad..605a72aefd 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2356,6 +2356,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 02581f12cc..e4ff94994e 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2651,6 +2651,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index 6f01f5df0d..fadff77863 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2216,6 +2216,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index d69e1589b7..12fb462089 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2416,6 +2416,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index b9440770af..2fa1ab95d3 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2585,6 +2585,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 274c743a2a..29404c99b4 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2393,6 +2393,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 42138cba69..a77a57f9c9 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2440,6 +2440,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index 57f7df559c..2321e33f50 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2437,6 +2437,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 1929d5801d..a720e9007b 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2580,6 +2580,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 8fe2d5a9d9..dcccfca363 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2415,6 +2415,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/spawn_int_def.h b/sysdeps/unix/sysv/linux/spawn_int_def.h new file mode 100644 index 0000000000..3be65b5711 --- /dev/null +++ b/sysdeps/unix/sysv/linux/spawn_int_def.h @@ -0,0 +1,25 @@ +/* Internal definitions for posix_spawn functionality. Linux version. + Copyright (C) 2021 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 _SPAWN_INT_DEF_H +#define _SPAWN_INT_DEF_H + +/* spawni.c implements closefrom by interacting over /proc/self/fd. */ +#define __SPAWN_SUPPORT_CLOSEFROM 1 + +#endif /* _SPAWN_INT_H */ diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c index 3b435e6c86..403bf609df 100644 --- a/sysdeps/unix/sysv/linux/spawni.c +++ b/sysdeps/unix/sysv/linux/spawni.c @@ -16,22 +16,16 @@ 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 -#include -#include -#include -#include -#include "spawn_int.h" +#include +#include +#include +#include /* The Linux implementation of posix_spawn{p} uses the clone syscall directly with CLONE_VM and CLONE_VFORK flags and an allocated stack. The new stack @@ -280,6 +274,14 @@ __spawni_child (void *arguments) if (__fchdir (action->action.fchdir_action.fd) != 0) goto fail; break; + + case spawn_do_closefrom: + { + int lowfd = action->action.closefrom_action.from; + int r = INLINE_SYSCALL_CALL (close_range, lowfd, ~0U, 0); + if (r != 0 && !__closefrom_fallback (lowfd, false)) + goto fail; + } break; } } } @@ -344,7 +346,9 @@ __spawnix (pid_t * pid, const char *file, /* We need at least a few pages in case the compiler's stack checking is enabled. In some configs, it is known to use at least 24KiB. We use 32KiB to be "safe" from anything the compiler might do. Besides, the - extra pages won't actually be allocated unless they get used. */ + extra pages won't actually be allocated unless they get used. + It also acts the slack for spawn_closefrom (including MIPS64 getdents64 + where it might use about 1k extra stack space. */ argv_size += (32 * 1024); size_t stack_size = ALIGN_UP (argv_size, GLRO(dl_pagesize)); void *stack = __mmap (NULL, stack_size, prot, diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 3412dcaf69..c48efc3dc8 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2371,6 +2371,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 04d540e619..60342c5eb4 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2470,6 +2470,7 @@ GLIBC_2.34 mtx_timedlock F GLIBC_2.34 mtx_trylock F GLIBC_2.34 mtx_unlock F GLIBC_2.34 openpty F +GLIBC_2.34 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.34 pthread_attr_getaffinity_np F GLIBC_2.34 pthread_attr_getguardsize F GLIBC_2.34 pthread_attr_getstack F