From patchwork Tue Dec 22 21:27:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 41519 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 527BC388A826; Tue, 22 Dec 2020 21:28:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 527BC388A826 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1608672483; bh=hpwwNfh3/ZiCV3o2rt4k8/DEgtLxEeGnVXg3dDrCiL4=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=sqvK2J4Jp2phwzcT2YqVHxFgR3mlA6Fu4aMoDDz+CcflP+S8UijLs8OmMxDmFEHvn bSBHT2xYY6hWZ5eo4xsVY2zd4+dWObVrAlaGh7oRZjzwqA9+oA+aT4A5C+oLtbJol7 2bO/yakvLCZr22zCo8CS6LbzeekdeDwRIg0zYglc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x729.google.com (mail-qk1-x729.google.com [IPv6:2607:f8b0:4864:20::729]) by sourceware.org (Postfix) with ESMTPS id E31FD383E814 for ; Tue, 22 Dec 2020 21:28:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E31FD383E814 Received: by mail-qk1-x729.google.com with SMTP id w79so13259283qkb.5 for ; Tue, 22 Dec 2020 13:28:00 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=hpwwNfh3/ZiCV3o2rt4k8/DEgtLxEeGnVXg3dDrCiL4=; b=r/K4naQAHisuGFXBRai5LJm5TKpp5Rlrmd5nji20gPSxGWRB1UN33Gd+7F1LCjQrMT LRImJRQ5uatk5AHXwzLhZhwmyfRbu/VzrKlYwk6LbLgWSbdTEWr5hUd9Hbl57vBlokA7 KeuQj3RUTcchDJeHpaT+xJb/qWqAYoh+UlwWHVAUpM94yKTh1p5wJWfvjKHkmZO7h9kj MTno/likFwuf6ZuzGJ+LIXTePYJcHKHlVGMzW1PFCuvUkabyEhfcapO2s8siT0hk9U9S ncGBSpF5v7+h+2UscHwULQdgEpfUt1b41f1nJ4P0rnsDdOj3lB/stlFe4XkzmgtQ/1bg MdjQ== X-Gm-Message-State: AOAM532kH37EQuIPg5QVedejeboyik0tCfYTKArpHgsmjjo3VBoC5bs4 /pysnoOB3fx+TegpOsD3m4zv4KuaUYP+bw== X-Google-Smtp-Source: ABdhPJwQROiIJEgfBGERVWiBBXa3ImLxDVlZGRW/pzuyv2CrlavwFUjORRuPzcFMAwJTuq3TTivijw== X-Received: by 2002:a37:4145:: with SMTP id o66mr23997943qka.4.1608672480205; Tue, 22 Dec 2020 13:28:00 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id h75sm4891404qke.130.2020.12.22.13.27.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Dec 2020 13:27:59 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 1/4] support: Add xclone Date: Tue, 22 Dec 2020 18:27:51 -0300 Message-Id: <20201222212754.387111-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: Florian Weimer Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" It is a wrapper for Linux close syscall, to simplify the call to the use only the most common arguments and remove architecture specific handling (such as ia64 different name and signature). --- support/Makefile | 1 + support/xclone.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ support/xsched.h | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 support/xclone.c create mode 100644 support/xsched.h diff --git a/support/Makefile b/support/Makefile index 3198eb5022..aecd27316e 100644 --- a/support/Makefile +++ b/support/Makefile @@ -89,6 +89,7 @@ libsupport-routines = \ xcalloc \ xchroot \ xclock_gettime \ + xclone \ xclose \ xconnect \ xcopy_file_range \ diff --git a/support/xclone.c b/support/xclone.c new file mode 100644 index 0000000000..e7efffb82b --- /dev/null +++ b/support/xclone.c @@ -0,0 +1,46 @@ +/* Auxiliary wrapper to issue the clone symbol. + Copyright (C) 2020 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 /* For _STACK_GROWS_{UP,DOWN}. */ +#include + +pid_t +xclone (int (*fn) (void *arg), void *arg, void *stack, size_t stack_size, + int flags) +{ + pid_t r = -1; + +#ifdef __linux__ +# ifdef __ia64__ + extern int __clone2 (int (*fn) (void *arg), void *stack, size_t stack_size, + int flags, void *arg, ...); + r = __clone2 (f, stack, stack_size, flags, arg, /* ptid */ NULL, + /* tls */ NULL, /* ctid */ ctid); +# else +# if _STACK_GROWS_DOWN + r = clone (fn, stack + stack_size, flags, arg, /* ptid */ NULL, + /* tls */ NULL, /* ctid */ NULL); +# elif _STACK_GROWS_UP + r = clone (fn, stack, flags, arg, /* ptid */ NULL, /* tls */ NULL, + &ctid); +# endif +# endif +#endif + + return r; +} diff --git a/support/xsched.h b/support/xsched.h new file mode 100644 index 0000000000..8523f03f82 --- /dev/null +++ b/support/xsched.h @@ -0,0 +1,36 @@ +/* Wrapper for sched.h functions. + Copyright (C) 2020 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 SUPPORT_XSCHED_H +#define SUPPORT_XSCHED_H + +__BEGIN_DECLS + +#include +#include + +#define DEFINE_STACK(name, size) \ + char name[size] __attribute__ ((aligned)) + +pid_t +xclone (int (*fn) (void *arg), void *arg, void *stack, size_t stack_size, + int flags); + +__END_DECLS + +#endif From patchwork Tue Dec 22 21:27:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 41520 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 DE71B388A837; Tue, 22 Dec 2020 21:28:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DE71B388A837 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1608672487; bh=OONTV5RzJSGCO01v4GeUC6OXz3Y3cwhHaXT2B45nLxk=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=BXPyj8T0UzZQezNbkZhJuevt1kGKZJ3HAzph9M1auMbtHW5p4KqRG4kHRYMMqAZxc PfLTQIkBQjdJWevBjxQvpiyAS8fSkfR+mZ2FapXqcLBO+u6MjbUgXRrEaAaxk9v6mo U7ZVgqJk1YoKU4LI5DNHu6rk/XNyiTITrbRPsNU8= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qv1-xf29.google.com (mail-qv1-xf29.google.com [IPv6:2607:f8b0:4864:20::f29]) by sourceware.org (Postfix) with ESMTPS id E9AEA383E805 for ; Tue, 22 Dec 2020 21:28:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E9AEA383E805 Received: by mail-qv1-xf29.google.com with SMTP id h16so6671763qvu.8 for ; Tue, 22 Dec 2020 13:28:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OONTV5RzJSGCO01v4GeUC6OXz3Y3cwhHaXT2B45nLxk=; b=kMox9/COVouWT+z+nREmqm6Zp7hnnRf5zSE8RdRLFjeLOHursOqUkZ7ObPklSVwtaS 80GBVuI/Sl7U6kPn1C3dy/qa5vAm4Ch5sIOejLBqjTCkj5ZVG5VvJYfpm4ZtMH7owNNF ARgf+BYBLpf02k6Yav+LmeoRCvIYTN5MVMp6NVyhAEJfPc17nbBlFbE7SNf3HOZ+lmE5 XXqepYdv7NKjxPH5HSExuMzSlscZzP6mYRjcDmTyJP8p1MCSvQmtaDXEHaJPsZPOzxre Ulj4Wi4g/mmbz0Kw4F7J7UoR5PO+asp31wk8juyIVn7mDEYaR0vh5PMczQglnOGPoeJM A8rA== X-Gm-Message-State: AOAM531EfrKJsl+uFW7JhssGSYU+r1o7UdXpodExNzw1T2djE7B+Kgd7 79mVI3V/lBx4xNatZipq5TvfLS7+jkoofA== X-Google-Smtp-Source: ABdhPJyM7G4ly/VFivhWUh/G1wxKxWt+ECWNVh8v1dIXVqcawNotLemEl+vdVRFn2fcWsO+1ksNNyA== X-Received: by 2002:ad4:4e31:: with SMTP id dm17mr24006519qvb.27.1608672481856; Tue, 22 Dec 2020 13:28:01 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id h75sm4891404qke.130.2020.12.22.13.28.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Dec 2020 13:28:01 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH v2 2/4] Linux: Add close_range Date: Tue, 22 Dec 2020 18:27:52 -0300 Message-Id: <20201222212754.387111-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201222212754.387111-1-adhemerval.zanella@linaro.org> References: <20201222212754.387111-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: Florian Weimer Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" Changes from previous version [1]: - Make the syscall not a cancellation entrypoint. - Move tst-clone.h to libsupport - Fixed typos. - Add clone (CLONE_FILES) and check if the close_range closes the parent table as well. - Remove file descriptors array - Add manual entry [1] https://patchwork.sourceware.org/project/glibc/patch/20201221215027.2176966-1-adhemerval.zanella@linaro.org/ --- It was added on Linux 5.9 (278a5fbaed89). 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). The tst-close_range-consts.py requires a toolchain with an updated kernel headers that provides the close_range.h UAPI kernel header. Checked on x86_64-linux-gnu on kernel v5.9 and v5.4. --- NEWS | 2 + include/bits/unistd_ext.h | 6 + manual/llio.texi | 31 +++ sysdeps/unix/sysv/linux/Makefile | 13 +- sysdeps/unix/sysv/linux/Versions | 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/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/bits/unistd_ext.h | 11 + 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 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/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 + .../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/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 + .../unix/sysv/linux/tst-close_range-consts.py | 49 +++++ sysdeps/unix/sysv/linux/tst-close_range.c | 198 ++++++++++++++++++ .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 35 files changed, 338 insertions(+), 2 deletions(-) create mode 100644 include/bits/unistd_ext.h create mode 100644 sysdeps/unix/sysv/linux/tst-close_range-consts.py create mode 100644 sysdeps/unix/sysv/linux/tst-close_range.c diff --git a/NEWS b/NEWS index 0820984547..9e829841f6 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,8 @@ Major new features: The 32-bit RISC-V port requires at least Linux 5.4, GCC 7.1 and binutils 2.28. +* On Linux, the close_range function has been added. + Deprecated and removed features, and other changes affecting compatibility: * The mallinfo function is marked deprecated. Callers should call 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 c0a53e1a6e..018e7933de 100644 --- a/manual/llio.texi +++ b/manual/llio.texi @@ -284,6 +284,37 @@ 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 emultation for +@c older kernels. + +The function @code{clode_range} closes the file descriptor from @var{lowfd} +to @var{maxfd} (included). This function is similar to call @code{close} in +specified file descriptor range. + +The @var{flags} add options on how the files are closes. Linux currently +supports. + +@vtable @code +@item CLOSE_RANGE_UNSHARE +It unshare the range of file descriptors from any other processes, instead +of closing them. +@end vtable + +The normal return value from @code{close} 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{flag} +is used. +@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 09604e128b..e06c2a1f0d 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -61,7 +61,7 @@ sysdep_routines += adjtimex clone umount umount2 readahead sysctl \ open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get \ timerfd_gettime timerfd_settime prctl \ process_vm_readv process_vm_writev clock_adjtime \ - time64-support pselect32 + time64-support pselect32 close_range CFLAGS-gethostid.c = -fexceptions CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables @@ -103,7 +103,8 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \ test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \ tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill \ - tst-tgkill tst-sysvsem-linux tst-sysvmsg-linux tst-sysvshm-linux + tst-tgkill tst-sysvsem-linux tst-sysvmsg-linux tst-sysvshm-linux \ + tst-close_range tests-internal += tst-ofdlocks-compat tst-sigcontext-get_pc CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables @@ -177,6 +178,14 @@ $(objpfx)tst-mman-consts.out: ../sysdeps/unix/sysv/linux/tst-mman-consts.py < /dev/null > $@ 2>&1; $(evaluate-test) $(objpfx)tst-mman-consts.out: $(sysdeps-linux-python-deps) +tests-special += $(objpfx)tst-close_range-consts.out +$(objpfx)tst-close_range-consts.out: ../sysdeps/unix/sysv/linux/tst-close_range-consts.py + $(sysdeps-linux-python) \ + ../sysdeps/unix/sysv/linux/tst-close_range-consts.py \ + $(sysdeps-linux-python-cc) \ + < /dev/null > $@ 2>&1; $(evaluate-test) +$(objpfx)tst-close_range-consts.out: $(sysdeps-linux-python-deps) + $(objpfx)tst-gettid: $(shared-thread-library) $(objpfx)tst-gettid-kill: $(shared-thread-library) $(objpfx)tst-tgkill: $(shared-thread-library) diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index c35f783e2a..e2a6fa763f 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -169,6 +169,9 @@ libc { } GLIBC_2.32 { } + GLIBC_2.33 { + close_range; + } GLIBC_PRIVATE { # functions used in other libraries __syscall_rt_sigqueueinfo; diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 4cc1c6a591..a52decb822 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2160,6 +2160,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 26ad9845e4..ed085c9b3c 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2242,6 +2242,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index bb9dfd4daf..88a17c2fdf 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -1920,6 +1920,7 @@ GLIBC_2.32 wprintf F GLIBC_2.32 write F GLIBC_2.32 writev F GLIBC_2.32 wscanf F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index 9ab3924888..a690962068 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -141,6 +141,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/bits/unistd_ext.h b/sysdeps/unix/sysv/linux/bits/unistd_ext.h index c315cc5cb8..799c59512c 100644 --- a/sysdeps/unix/sysv/linux/bits/unistd_ext.h +++ b/sysdeps/unix/sysv/linux/bits/unistd_ext.h @@ -33,4 +33,15 @@ not detached and has not been joined. */ extern __pid_t gettid (void) __THROW; +/* Unshare the file descriptor table before closing file descriptors. */ +#define CLOSE_RANGE_UNSHARE (1U << 1) + +/* 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 diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 14a84dac8f..d37882413c 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2104,6 +2104,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 5c8502f3d3..61450e47d5 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2063,6 +2063,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 4f0d3c1eb5..672ff8a002 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2229,6 +2229,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index e3b345b803..53e53005e9 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2095,6 +2095,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index c4891479d3..cc0d93b381 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2175,6 +2175,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 143b0163b4..b4acf52c41 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2155,6 +2155,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index b2295f1937..fadbf99d4b 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2146,6 +2146,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index aa9c6a4dca..c456ebcea3 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2152,6 +2152,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 5939588ad5..5ed54e7c94 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2146,6 +2146,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index 92556c4237..67b611ef6d 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2193,6 +2193,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 26c93dff05..ed0f239cd5 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2202,6 +2202,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index c2ca00709e..a4b9900036 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2065,6 +2065,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 0ea50dc851..e5d666dab3 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2355,6 +2355,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index 0263e284d4..f8c34aca7c 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -595,6 +595,7 @@ GLIBC_2.33 clock_nanosleep F GLIBC_2.33 clock_settime F GLIBC_2.33 clone F GLIBC_2.33 close F +GLIBC_2.33 close_range F GLIBC_2.33 closedir F GLIBC_2.33 closelog F GLIBC_2.33 confstr F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 1626c5351f..6042d42aba 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2122,6 +2122,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index a66426eb4d..46d2de3030 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2200,6 +2200,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index ab351873ae..9fda4babba 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2101,6 +2101,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index d36f228192..110f7ebf22 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2067,6 +2067,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 59b4313280..1b31685a24 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2191,6 +2191,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 266dcdfa08..9ad88bf7b3 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2118,6 +2118,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 01ec2bfa95..53575669c7 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -101,3 +101,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-consts.py b/sysdeps/unix/sysv/linux/tst-close_range-consts.py new file mode 100644 index 0000000000..3a0d4423e8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-close_range-consts.py @@ -0,0 +1,49 @@ +#!/usr/bin/python3 +# Test that glibc's unistd_ext.h constants match the kernel's. +# Copyright (C) 2020 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 +# . + +import argparse +import sys + +import glibcextract +import glibcsyscalls + + +def main(): + """The main entry point.""" + parser = argparse.ArgumentParser( + description="Test that glibc's unistd_ext.h constants match " + "the kernel's.") + parser.add_argument('--cc', metavar='CC', + help='C compiler (including options) to use') + args = parser.parse_args() + linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) + linux_version_glibc = (5, 9) + sys.exit(glibcextract.compare_macro_consts( + '#define _GNU_SOURCE 1\n' + '#include \n', + '#define _GNU_SOURCE 1\n' + '#include \n', + args.cc, + 'CLOSE_RANGE_.*', + None, + linux_version_glibc > linux_version_headers, + linux_version_headers > linux_version_glibc)) + +if __name__ == '__main__': + main() 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..1a127bb9cb --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-close_range.c @@ -0,0 +1,198 @@ +/* Test for the close_range system call. + Copyright (C) 2020 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 void +close_range_test_common (int lowfd, unsigned int flags) +{ + const int maximum_fd = lowfd + NFDS; + const int half_fd = maximum_fd / 2; + const int gap_1 = maximum_fd - 8; + + /* Close half of the descriptors and check result. */ + { + int r = close_range (lowfd, half_fd, flags); + if (r == -1 && errno == ENOSYS) + FAIL_UNSUPPORTED ("close_range not supported"); + TEST_COMPARE (r, 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 (57); + xclose (78); + xclose (81); + xclose (82); + xclose (84); + xclose (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 remmaining 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 +__attribute__((used)) +close_range_test (void) +{ + struct support_descriptors *descrs = support_descriptors_list (); + + int lowfd = xopen ("/dev/null", O_RDONLY | O_CLOEXEC, 0600); + for (int i = 0; i < NFDS; i++) + xopen ("/dev/null", O_RDONLY | O_CLOEXEC, 0600); + + 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 +__attribute__((used)) +close_range_test_subprocess (void) +{ + struct support_descriptors *descrs = support_descriptors_list (); + + int lowfd = xopen ("/dev/null", O_RDONLY | O_CLOEXEC, 0600); + for (int i = 0; i < NFDS; i++) + xopen ("/dev/null", O_RDONLY | O_CLOEXEC, 0600); + + enum { stack_size = 4096 }; + DEFINE_STACK (stack, stack_size); + pid_t pid = xclone (close_range_test_fn, (void*) (uintptr_t) lowfd, 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); + + 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 +__attribute__((used)) +close_range_unshare_test (void) +{ + int lowfd = xopen ("/dev/null", O_RDONLY | O_CLOEXEC, 0600); + for (int i = 0; i < NFDS; i++) + xopen ("/dev/null", O_RDONLY | O_CLOEXEC, 0600); + + struct support_descriptors *descrs = support_descriptors_list (); + + enum { stack_size = 4096 }; + DEFINE_STACK (stack, stack_size); + pid_t pid = xclone (close_range_unshare_test_fn, (void*) (uintptr_t) lowfd, + 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); + + for (int i = 0; i < NFDS; i++) + TEST_VERIFY (fcntl (i, F_GETFL) > -1); + + support_descriptors_check (descrs); + support_descriptors_free (descrs); + + TEST_COMPARE (close_range (lowfd, lowfd + NFDS, 0), 0); +} + +static int +do_test (void) +{ + close_range_test (); + close_range_test_subprocess (); + close_range_unshare_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 4fff61818b..5089a21981 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2076,6 +2076,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 102ed47a9c..c3db0fc7ca 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2173,6 +2173,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 close_range F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F From patchwork Tue Dec 22 21:27:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 41521 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 EFBD9388A83E; Tue, 22 Dec 2020 21:28:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EFBD9388A83E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1608672491; bh=tSGaLLMpvtvnoz0IDnzPa0sOxqxH4uAxFzpd53CWswU=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=lM3Ng1+XZZUUlJFG0UX2W2UcTSzYiW8OK4mz3qmk55lV0n+sqkssoAU1lt+avPUyJ RxHL1AwSdf1E7+e3VWS/JSNiCH7qnHqXeRKOGn03rib3IYptonoENrPk3EvY3YqqJt VEgptuvq9SKrwcJZlv8kPHSyVHKZm8KXqah6sF+w= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x735.google.com (mail-qk1-x735.google.com [IPv6:2607:f8b0:4864:20::735]) by sourceware.org (Postfix) with ESMTPS id E3E5F383E814 for ; Tue, 22 Dec 2020 21:28:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E3E5F383E814 Received: by mail-qk1-x735.google.com with SMTP id f26so11635805qka.0 for ; Tue, 22 Dec 2020 13:28:04 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tSGaLLMpvtvnoz0IDnzPa0sOxqxH4uAxFzpd53CWswU=; b=JLKd9/qtabUiBnD2IyqcuLsKKLg7gnIykJQ+CVPM0RbShITq4OP1/2k0WKM/nOPz1z bqunnemZwOX38ATldrNI++RNIaW1s1ld/a81I52bxBEZbs4lg8cpIJYZLtT9K2X+Q7zf qGSMEGGifvPq7lh+ZLh3PUi0cB9cA9NQ9E60gWymtO/K6fHhNSx8kUMFbTvqEraRrdZC i7XaHJlfsR5IEsvER4VnP5AWvFMz83aW6uii8hgzCOMFXAaSO25YDLbZjBX8cUyqsq/h j3/WpqPRpDquD/i7X0yJJZsASXIIjPq5itwtOltOQrs59udlKSe4aL3F2SjGNxYdYNJg X+xg== X-Gm-Message-State: AOAM533U6uXBYEueJCR+ZPPzLcWf+zU2sftm0CTxE+VmRhr/9Jsxdz/z MaHil5StDTwq/ap1GRwv4NmlLhbCorngCw== X-Google-Smtp-Source: ABdhPJziiG0RQbRSaKtdx2jmwVQ1e0GVMaLwMdQ35VzJZPWzI1G1V3nhH6TXkAJexMUbMRDlsrjmLg== X-Received: by 2002:a37:a14a:: with SMTP id k71mr24175283qke.33.1608672483577; Tue, 22 Dec 2020 13:28:03 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id h75sm4891404qke.130.2020.12.22.13.28.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Dec 2020 13:28:03 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH v2 3/4] io: Add closefrom [BZ #10353] Date: Tue, 22 Dec 2020 18:27:53 -0300 Message-Id: <20201222212754.387111-3-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201222212754.387111-1-adhemerval.zanella@linaro.org> References: <20201222212754.387111-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: Florian Weimer Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" Changes from previous version [1]: - Use __close_nocancel_nostatus on generic implementation. - Make the symbol not a cancellation entrypoint. - Add manual entry. [1] https://patchwork.sourceware.org/project/glibc/patch/20201221215027.2176966-2-adhemerval.zanella@linaro.org/ --- The symbol closes all open file descriptors greater than or equal to input argument. Negative values are campled 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.9 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 | 5 +- io/Versions | 1 + io/closefrom.c | 33 ++++ io/tst-closefrom.c | 143 ++++++++++++++++++ manual/llio.texi | 14 ++ posix/unistd.h | 6 + sysdeps/mach/hurd/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/Makefile | 2 +- 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 | 88 +++++++++++ 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, 362 insertions(+), 3 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 9e829841f6..e6446f0548 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,10 @@ Major new features: * On Linux, the close_range function has been added. +* 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 mallinfo function is marked deprecated. Callers should call diff --git a/include/unistd.h b/include/unistd.h index 54becbc9eb..d48ad6c799 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -153,6 +153,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 33f5b0b867..56a788c2d5 100644 --- a/io/Makefile +++ b/io/Makefile @@ -55,7 +55,8 @@ routines := \ posix_fadvise posix_fadvise64 \ posix_fallocate posix_fallocate64 \ sendfile sendfile64 copy_file_range \ - utimensat futimens file_change_detection + utimensat futimens file_change_detection \ + closefrom others := pwd test-srcs := ftwtest @@ -69,7 +70,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ tst-fts tst-fts-lfs tst-open-tmpfile \ tst-copy_file_range tst-getcwd-abspath tst-lockf \ tst-ftw-lnk tst-file_change_detection tst-lchmod \ - tst-ftw-bz26353 + tst-ftw-bz26353 tst-closefrom # Likewise for statx, but we do not need static linking here. tests-internal += tst-statx diff --git a/io/Versions b/io/Versions index 49c4d2d40a..fa33452881 100644 --- a/io/Versions +++ b/io/Versions @@ -135,6 +135,7 @@ libc { GLIBC_2.33 { stat; stat64; fstat; fstat64; lstat; lstat64; fstatat; fstatat64; mknod; mknodat; + closefrom; } GLIBC_PRIVATE { __libc_fcntl64; diff --git a/io/closefrom.c b/io/closefrom.c new file mode 100644 index 0000000000..be95ee40c8 --- /dev/null +++ b/io/closefrom.c @@ -0,0 +1,33 @@ +/* Close a range of file descriptors. + Copyright (C) 2020 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 + +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..47b50b74b6 --- /dev/null +++ b/io/tst-closefrom.c @@ -0,0 +1,143 @@ +/* Smoke test for the closefrom. + Copyright (C) 2020 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 +closefrom_test (void) +{ + struct support_descriptors *descrs = support_descriptors_list (); + + int lowfd = xopen ("/dev/null", O_RDONLY | O_CLOEXEC, 0600); + for (int i = 0; i < NFDS; i++) + xopen ("/dev/null", O_RDONLY | O_CLOEXEC, 0600); + + const int maximum_fd = lowfd + NFDS; + const int half_fd = maximum_fd / 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 (35); + xclose (38); + xclose (42); + xclose (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 | O_CLOEXEC, 0600); + for (;;) + { + int fd = open ("/dev/null", O_RDONLY | O_CLOEXEC, 0600); + if (fd == -1) + { + if (errno != EMFILE) + FAIL_EXIT1 ("create_temp_file: %m"); + break; + } + } + + 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 018e7933de..d2cf7bbabd 100644 --- a/manual/llio.texi +++ b/manual/llio.texi @@ -314,6 +314,20 @@ is used. @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 large or equal +then @var{lowfd}. This function is similar to call @code{close} in specified +file descriptor range. + +@table @code +@item EINVAL +The @var{lowfd} value is larger than @var{maxfd} or an unsupported @var{flag} +is used. +@end table +@end deftypefun @node I/O Primitives @section Input and Output Primitives diff --git a/posix/unistd.h b/posix/unistd.h index 32b8161619..652fed4616 100644 --- a/posix/unistd.h +++ b/posix/unistd.h @@ -352,6 +352,12 @@ extern __off64_t lseek64 (int __fd, __off64_t __offset, int __whence) __THROW. */ extern int close (int __fd); +#ifdef __USE_GNU +/* 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 7a5eb66b85..fce67cf3ca 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2191,6 +2191,7 @@ GLIBC_2.32 thrd_current F GLIBC_2.32 thrd_equal F GLIBC_2.32 thrd_sleep F GLIBC_2.32 thrd_yield F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index e06c2a1f0d..59ee6b5b5a 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -61,7 +61,7 @@ sysdep_routines += adjtimex clone umount umount2 readahead sysctl \ open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get \ timerfd_gettime timerfd_settime prctl \ process_vm_readv process_vm_writev clock_adjtime \ - time64-support pselect32 close_range + time64-support pselect32 close_range 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 a52decb822..811d3b3cd9 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2161,6 +2161,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index ed085c9b3c..d0bc011811 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2243,6 +2243,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index 88a17c2fdf..c4e26b3cf6 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -1921,6 +1921,7 @@ GLIBC_2.32 write F GLIBC_2.32 writev F GLIBC_2.32 wscanf F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 3b0a47e967..5ccd1fb07f 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -144,6 +144,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index a690962068..5043e483b8 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -142,6 +142,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/closefrom.c b/sysdeps/unix/sysv/linux/closefrom.c new file mode 100644 index 0000000000..ba98fccd39 --- /dev/null +++ b/sysdeps/unix/sysv/linux/closefrom.c @@ -0,0 +1,35 @@ +/* Close a range of file descriptors. Linux version. + Copyright (C) 2020 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..461582792d --- /dev/null +++ b/sysdeps/unix/sysv/linux/closefrom_fallback.c @@ -0,0 +1,88 @@ +/* Close a range of file descriptors. Linux version. + Copyright (C) 2020 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. + In this case it loops over RLIMIT_NOFILE / rlim_cur until it frees + a file descriptor to iterate over /proc. */ + if (errno != EMFILE) + goto err; + + int maxfd = __getdtablesize (); + for (int i = from; i < maxfd; i++) + if (__close_nocancel (i) == 0) + 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; + + 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; + + __close_nocancel (fd); + } + } + + 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 d37882413c..6f3718cd14 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2105,6 +2105,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 61450e47d5..84b474dba4 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2064,6 +2064,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 672ff8a002..4c1399102e 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2230,6 +2230,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 53e53005e9..9fcaa40c34 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2096,6 +2096,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 25f2d1c08f..ccb780d9c7 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -145,6 +145,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index cc0d93b381..3afaa1c70e 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2176,6 +2176,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index b4acf52c41..266063d0e8 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2156,6 +2156,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 13d374a031..5d893ec4d1 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2152,6 +2152,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index fadbf99d4b..6207a15a09 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2147,6 +2147,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 4c786070d0..860e5fecfa 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2144,6 +2144,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index c456ebcea3..daed5ae2a8 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2153,6 +2153,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 5ed54e7c94..7b6edfe8f5 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2147,6 +2147,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index 67b611ef6d..9dd7d64500 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2194,6 +2194,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index ed0f239cd5..c561e5cf36 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2203,6 +2203,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index f04b167788..d25bf75ed3 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2235,6 +2235,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index a4b9900036..248fab8212 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2066,6 +2066,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index e5d666dab3..d02fa6b3d2 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2356,6 +2356,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index f8c34aca7c..56d1a16b2a 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -597,6 +597,7 @@ GLIBC_2.33 clone F GLIBC_2.33 close F GLIBC_2.33 close_range F GLIBC_2.33 closedir F +GLIBC_2.33 closefrom F GLIBC_2.33 closelog F GLIBC_2.33 confstr F GLIBC_2.33 connect F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 6042d42aba..8fcd329728 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2123,6 +2123,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 46d2de3030..b06cc94710 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2201,6 +2201,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 9fda4babba..6ede1579ca 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2102,6 +2102,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 22ceaa3d87..0f426028a1 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2070,6 +2070,7 @@ GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index 110f7ebf22..8637b683d6 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2068,6 +2068,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 1b31685a24..dc7c01f734 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2192,6 +2192,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 9ad88bf7b3..67d361c881 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2119,6 +2119,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 5089a21981..94bb5a0fa7 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2077,6 +2077,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index c3db0fc7ca..e94ce733ab 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2174,6 +2174,7 @@ GLIBC_2.32 sigdescr_np F GLIBC_2.32 strerrordesc_np F GLIBC_2.32 strerrorname_np F GLIBC_2.33 close_range F +GLIBC_2.33 closefrom F GLIBC_2.33 fstat F GLIBC_2.33 fstat64 F GLIBC_2.33 fstatat F From patchwork Tue Dec 22 21:27:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 41522 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 02BDE388C004; Tue, 22 Dec 2020 21:28:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 02BDE388C004 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1608672493; bh=+q0Pk2Vh6BuWBlEXfUYMW6jjEyQjAPc8Q3tpSbYQ+J0=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=R9PpR68Xyeatu0vTx8P2oemkYPsFWErxMAVvaZYNguamD65rLFu9wXRTKI2uZcpk1 Ydjw3mOuKQhKOFesL0+HhGuD7tmg2g/hzSY7f5mgOUxgdOBqWsKrGf1vki3ZIGc1jN yU8q3/NL6qC1MNtTRbevQ9fcUmCNA/yYvIGD/HOg= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x733.google.com (mail-qk1-x733.google.com [IPv6:2607:f8b0:4864:20::733]) by sourceware.org (Postfix) with ESMTPS id 193CB383E805 for ; Tue, 22 Dec 2020 21:28:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 193CB383E805 Received: by mail-qk1-x733.google.com with SMTP id w79so13259541qkb.5 for ; Tue, 22 Dec 2020 13:28:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+q0Pk2Vh6BuWBlEXfUYMW6jjEyQjAPc8Q3tpSbYQ+J0=; b=s+rKn/maEyUAsy3JjbokzY7ORnAV9J260CmiZ4IAs//X0lg+ORy4uzqRSddi6345WI 6q+W+YRc+a+tHBcO3gD5lS3HFk8l8gMYNasniQQoqB2K+CJAJ47kDz9O7Kqeq9m805By Yw6JHzxPd49djddSxyZvJXk5BHrd91lDRNc/u/LTmMI7jzHNoLp5dkX1klJ4iCzzZPRo AqtqV9oMnw/NYJPy4iYjHXLbJ+XgDcfNy2byEOeRKqA7VeB0JVvCuGe8nwhmEXNNzi6s dRQBMr+1dc1/rWH7dXWzcUZl42MVGeWNLjqJvE3QVusNNDDDeB9EqQRwJUv5wQGa9PC7 OMjA== X-Gm-Message-State: AOAM531QBjhreerwWUTdUuMuyVYqj+VbexxE12sSTDbAXw/cGCpHfck4 Xks47faO+pIZjv1MrRgElKXigg2PllnxJg== X-Google-Smtp-Source: ABdhPJxhRGdk/D+tHopzE0B9QLncNT0ORkqIcFEwUM7JvII5pXwYAV5KJD9vL12H70XsURp6/Tv+YA== X-Received: by 2002:a37:9c16:: with SMTP id f22mr23802826qke.67.1608672485310; Tue, 22 Dec 2020 13:28:05 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id h75sm4891404qke.130.2020.12.22.13.28.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Dec 2020 13:28:04 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH v2 4/4] posix: Add posix_spawn_file_actions_closefrom Date: Tue, 22 Dec 2020 18:27:54 -0300 Message-Id: <20201222212754.387111-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201222212754.387111-1-adhemerval.zanella@linaro.org> References: <20201222212754.387111-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: Florian Weimer Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" Change from previous version [1]: - Return EINVAL for __posix_spawn_file_actions_addclosefrom fallback. - Fixed typos. - Remove posix/spawn_int_abi.h. - Remove array usage on posix/tst-spawn5.c test. [1] https://patchwork.sourceware.org/project/glibc/patch/20201221215027.2176966-3-adhemerval.zanella@linaro.org/ --- 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 posix_spawn is safe to be implemented by interacting 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 + posix/Makefile | 4 +- posix/Versions | 3 + 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 | 272 ++++++++++++++++++ sysdeps/generic/spawn_int_abi.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/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_abi.h | 25 ++ sysdeps/unix/sysv/linux/spawni.c | 35 ++- .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 46 files changed, 465 insertions(+), 16 deletions(-) create mode 100644 posix/spawn_faction_addclosefrom.c create mode 100644 posix/tst-spawn5.c create mode 100644 sysdeps/generic/spawn_int_abi.h create mode 100644 sysdeps/unix/sysv/linux/spawn_int_abi.h diff --git a/NEWS b/NEWS index e6446f0548..60a13edcbe 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,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 has been added, enabling + posix_spawn and posix_spawnp to close all file descriptors greater than + 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 mallinfo function is marked deprecated. Callers should call diff --git a/posix/Makefile b/posix/Makefile index 4bfc8d942c..d40636547e 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 \ @@ -102,7 +103,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-wordexp-nocmd tst-spawn5 tests-internal := bug-regex5 bug-regex20 bug-regex33 \ tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \ tst-glob_lstat_compat tst-spawn4-compat @@ -258,6 +259,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 7d06a6d0c0..95d7b01126 100644 --- a/posix/Versions +++ b/posix/Versions @@ -147,6 +147,9 @@ libc { } GLIBC_2.30 { } + GLIBC_2.33 { + posix_spawn_file_actions_addclosefrom_np; + } GLIBC_PRIVATE { __libc_fork; __libc_pread; __libc_pwrite; __nanosleep_nocancel; __pause_nocancel; diff --git a/posix/spawn.h b/posix/spawn.h index be6bd591a3..e81b4a4e90 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 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..3b5e73fe32 --- /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) 2020 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 098385e1e0..33045e2c7f 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 9be54c0416..512dcea0da 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..9bdabd2387 --- /dev/null +++ b/posix/tst-spawn5.c @@ -0,0 +1,272 @@ +/* Tests for posix_spawn signal handling. + Copyright (C) 2020 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. */ +static char *initial_argv[7]; + +#define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +#define NFDS 100 + +/* Called on process re-execution. */ +_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 int fd = strtol (argv[i+1], &endptr, 10); + if (*endptr != '\0' || fd < 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 closed", 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 = xopen ("/dev/null", O_WRONLY, 0); + for (int i = 1; i < NFDS; i++) + xopen ("/dev/null", O_WRONLY, 0); + 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 (57); + xclose (78); + xclose (81); + xclose (82); + xclose (84); + xclose (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_abi.h b/sysdeps/generic/spawn_int_abi.h new file mode 100644 index 0000000000..bfc8961598 --- /dev/null +++ b/sysdeps/generic/spawn_int_abi.h @@ -0,0 +1,24 @@ +/* Internal ABI specific for posix_spawn functionality. Generic version. + Copyright (C) 2020 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_ABI_H +#define _SPAWN_INT_ABI_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 fce67cf3ca..5b23d62b5d 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2201,6 +2201,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c index 178b271e4e..9ea4fc972f 100644 --- a/sysdeps/mach/hurd/spawni.c +++ b/sysdeps/mach/hurd/spawni.c @@ -600,6 +600,10 @@ __spawni (pid_t *pid, const char *file, 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 943a598771..d05d2c8520 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 811d3b3cd9..65d5c3cee4 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2171,5 +2171,6 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index d0bc011811..ac55ceba70 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2253,6 +2253,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index c4e26b3cf6..24e623875d 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -1931,5 +1931,6 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 5ccd1fb07f..50086104ea 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -154,6 +154,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 _Exit F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index 5043e483b8..a4ebfccc74 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -152,6 +152,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 _Exit F diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 6f3718cd14..4b45f0a8a0 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2115,5 +2115,6 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 84b474dba4..b574604263 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2074,6 +2074,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 4c1399102e..51795cd925 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2240,6 +2240,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 9fcaa40c34..bafbc98f69 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2106,6 +2106,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index ccb780d9c7..8c3fc11399 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -155,6 +155,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 _Exit F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 3afaa1c70e..10a11773f2 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2186,6 +2186,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 266063d0e8..e908a7a19a 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2166,5 +2166,6 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 5d893ec4d1..d8f3ff6dec 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2162,5 +2162,6 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 6207a15a09..1c41ce7c83 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2157,6 +2157,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 860e5fecfa..dcec226837 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2154,6 +2154,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index daed5ae2a8..022a7ec721 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2163,6 +2163,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 7b6edfe8f5..a312612703 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2157,6 +2157,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index 9dd7d64500..d4e4096a11 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2204,5 +2204,6 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index c561e5cf36..01705658c0 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2213,6 +2213,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index d25bf75ed3..eea881eeae 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2245,6 +2245,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 248fab8212..bb346370ad 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2076,6 +2076,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index d02fa6b3d2..0dad53bc80 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2366,5 +2366,6 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index 56d1a16b2a..7ee1f2e189 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -1304,6 +1304,7 @@ GLIBC_2.33 posix_openpt F GLIBC_2.33 posix_spawn F GLIBC_2.33 posix_spawn_file_actions_addchdir_np F GLIBC_2.33 posix_spawn_file_actions_addclose F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 posix_spawn_file_actions_adddup2 F GLIBC_2.33 posix_spawn_file_actions_addfchdir_np F GLIBC_2.33 posix_spawn_file_actions_addopen F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 8fcd329728..51fc25677d 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2133,5 +2133,6 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index b06cc94710..61bda38fb0 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2211,6 +2211,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 6ede1579ca..a73bc16ae0 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2112,6 +2112,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 0f426028a1..974090f39b 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2080,6 +2080,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index 8637b683d6..910c8e752d 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2078,6 +2078,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index dc7c01f734..fabbdaeef0 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2202,6 +2202,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 67d361c881..0ad7f0b18c 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2129,6 +2129,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/spawn_int_abi.h b/sysdeps/unix/sysv/linux/spawn_int_abi.h new file mode 100644 index 0000000000..84b31104c5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/spawn_int_abi.h @@ -0,0 +1,25 @@ +/* Internal ABI specific for posix_spawn functionality. Linux version. + Copyright (C) 2020 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_ABI_H +#define _SPAWN_INT_ABI_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 f157bfffd2..c337c7a6a1 100644 --- a/sysdeps/unix/sysv/linux/spawni.c +++ b/sysdeps/unix/sysv/linux/spawni.c @@ -16,22 +16,17 @@ 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 -#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 +275,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)) + goto fail; + } break; } } } @@ -344,7 +347,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 94bb5a0fa7..c17d5d93c3 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2087,6 +2087,7 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index e94ce733ab..e8ff4b7cc9 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2184,5 +2184,6 @@ GLIBC_2.33 lstat64 F GLIBC_2.33 mallinfo2 F GLIBC_2.33 mknod F GLIBC_2.33 mknodat F +GLIBC_2.33 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.33 stat F GLIBC_2.33 stat64 F