From patchwork Wed Jul 31 18:31:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 170207 Delivered-To: patch@linaro.org Received: by 2002:ac9:2daa:0:0:0:0:0 with SMTP id g42csp6295159oce; Wed, 31 Jul 2019 11:32:23 -0700 (PDT) X-Google-Smtp-Source: APXvYqzP1T/3oaHOY7uoIHiDEkvQJ42I52Wcb8eLKJ2f6U3e2h2AluRKcU7wn3/h7APyUnOnKZxn X-Received: by 2002:a63:7e1d:: with SMTP id z29mr114987338pgc.346.1564597943464; Wed, 31 Jul 2019 11:32:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564597943; cv=none; d=google.com; s=arc-20160816; b=ODVlgZW+avPKaUFLN7S46X4wE9lRZJJSN3miZUCtHneISvzu3oPcmVza3UPT9Hhkhk lCkhLQ0ot8kru5QWKGAQ2d8sxgBjzRd8zn8zEIKIK/lB9LdnizAu/UfP3NlB7JFksDI9 Zhv//bIcpSml5zuXHuPugh5CZLPf93C/hI6a2qYbGFgzNOqlb5GyCVucsHUwFeVeC6Yu P1i1A0lSfJ2kxA+4EAag7mou4Av7n8Jw9YNHP41qPu4UPj7U8NDZgs24zjxBzR65kmyE g1HWErdvYFpL+vK22gtv8gWa4wXBiEH9mJl4ZkJT4oi5VpCmpyMo8k3hDNQAR86ZAhWK 9HCA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=Qz0DjXicIgB6d19nq1z7PECVNaviQddausDcUHlrfcQ=; b=Z+F0E86R6m46MYYV10gpozkdFakCWStxsQyy4zMUCSTflrg6JElapEQ+xzj6KoOpS3 LNT2S/z6KQ9cKOnMsU3ZV9qCggrdvfW7EIfTkYUDMaZtB5pq0QzpNfPctP57dnaf8/PN zrWzcuK41ADgQ73VVd3ToE8k6UK61LqYBhvUHSkpI7MALMFhGz7d+0i8naC0Pbl2ntJ5 dGG4Y/ubGdSlwZTGP4DsYvFk8mm+kzy9G8rrDCWp5eFiIIbtj7tqFtBb7t0+PzL9IXS5 KiyvsRlBZHmcIwSnWrhmnmUpcXt4StpaLJX8PYfLMQqHpbX8pT3kYWaf5IdVzCzuRSzN 7Prw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b="GI+TOk/H"; dkim=pass header.i=@linaro.org header.s=google header.b=I95qmbOQ; spf=pass (google.com: domain of libc-alpha-return-104076-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-104076-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id o13si1962256pjr.101.2019.07.31.11.32.23 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 Jul 2019 11:32:23 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-104076-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b="GI+TOk/H"; dkim=pass header.i=@linaro.org header.s=google header.b=I95qmbOQ; spf=pass (google.com: domain of libc-alpha-return-104076-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-104076-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=efEAFYO69k2Nv3YaA8lPFlqWmHXEKXz PwT3n73J6a9kmQnIfhZDmRBIVBnG3imJ6RbtyImZvZZSrMd8T7BU5uMt3DqYRpDF Xz+GbaNk9/WqAEUfjyOGvTQ9DTAr7EB1A/X2C+rykLrdV5A7DlloL86HfVgB00hS hnoqkRkbhyWA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=50M+YaXe8Oh44EFniPzLdY5NMfU=; b=GI+TO k/HvUG6OR/ikGU5p8Q4KaSuoV5zacjvvAqj+MMM79wNQfhVXB6Zz2y+HxatRLHRo +27qbID+yuLHBHyqDJV66I5CBphdM0f0Wy/szBY5ZKUBxxHIWAuX6vW5yGyq/2xu CDX/IAln17UPUTN2qafwqoWrmWe0P8TbVjLb+8= Received: (qmail 123174 invoked by alias); 31 Jul 2019 18:31:53 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 123090 invoked by uid 89); 31 Jul 2019 18:31:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=Plus, usages X-HELO: mail-qt1-f195.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=Qz0DjXicIgB6d19nq1z7PECVNaviQddausDcUHlrfcQ=; b=I95qmbOQkNPgDh6Kxxyh0H5JS8jdYKcDSyo117jkL1Rp4ly3zSMm42ObtcjWveAPnG HPevKc6EHO6/zDiVB7ZhRmDJn6x25brJ7ug85BDe2t6/i7OnWH97bT6bLh/Nu0lqCohn SUCVU8H4N9gfTybu9Wi5xdX/R0Cu/t0Qbv/473x3YXJAX1Cr2NvVh6jGKW9H7DcVSsda 8X5dceHo7jEHkU9GQ5YZCUXwjM9KQm2TRndAjNqtHP/YZz5XuutzxjDYE7/y5+p0kBHg WwOaMLyZ4BrdnweRFAtan1GBzEkj+gTBH2PEOB9SaSY1Fx/KPpddxCqZkf4TkO07ZzBm xEHw== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 2/5] posix: Add posix_spawn_file_actions_closefrom Date: Wed, 31 Jul 2019 15:31:33 -0300 Message-Id: <20190731183136.21545-2-adhemerval.zanella@linaro.org> In-Reply-To: <20190731183136.21545-1-adhemerval.zanella@linaro.org> References: <20190731183136.21545-1-adhemerval.zanella@linaro.org> Changes from previous version: - Remove __spawn_valid_fd check on posix_spawn_file_actions_addclosefrom. - Rename __SUPPORT_SPAWN_CLOSEFROM macro to __SPAWN_SUPPORT_CLOSEFROM. - Use getdents64 instead of changing add internal __opendir_inplace. Regarding the lseek to reset the descriptor offset after each file removal, I think that by iteracting the descriptor based on getdents64 results there is no real need for it. The kernel returns the fds sequentially and there is no open operations done concurrently, so both my expectations and the tests result is getdents returns an updated version after a close() call. -- 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. There are some discussions on BZ#10353 [2], although the bug itself asks for a generic solution (similar to the closeall provided by some BSD). The posix_spawn is safe to be implemented by interacting over /proc/self/fd, the Linux spawni.c does not use CLONE_FILES, so the helper process has its 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 [3] (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. * posix/Makefile (routines): Add spawn_faction_addclosefrom. (tests): Add tst-spawn5. (tst-spawn5-ARGS): New rule. * posix/Versions [GLIBC_2.30] (libc): Add posix_spawn_file_actions_addclosefrom_np. * posix/spawn.h (posix_spawn_file_actions_addclosefrom_np): New prototype. * posix/spawn_faction_addclosefrom.c: New file * posix/spawn_faction_destroy.c (__posix_spawn_file_actions_destroy): Handle spawn_do_closefrom. * posix/spawn_int.h (__spawn_action): Add closefrom_action and spawn_do_closefrom. * posix/spawn_int_abi.h: New file. * sysdeps/unix/sysv/linux/spawn_int_abi.h: Likewise. * posix/tst-spawn5.c: Likewise. * sysdeps/mach/hurd/spawni.c (__spawni, __spawni_child): Handle spawn_do_closefrom. * sysdeps/posix/spawni.c (__spawni_child): Likewise. * sysdeps/unix/sysv/linux/spawni.c (__spawni_child, __spawnix): Likewise. (spawn_closefrom): New function. * sysdeps/mach/hurd/i386/libc.abilist (2.30): Add posix_spawn_file_actions_addclosefrom_np. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/arm/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/csky/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise. --- posix/Makefile | 5 +- posix/Versions | 1 + posix/spawn.h | 7 + posix/spawn_faction_addclosefrom.c | 58 +++++ posix/spawn_faction_destroy.c | 1 + posix/spawn_int.h | 6 + posix/spawn_int_abi.h | 27 +++ posix/tst-spawn5.c | 210 ++++++++++++++++++ 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/arm/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 + .../unix/sysv/linux/microblaze/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 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/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/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 | 62 +++++- .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 39 files changed, 425 insertions(+), 12 deletions(-) create mode 100644 posix/spawn_faction_addclosefrom.c create mode 100644 posix/spawn_int_abi.h create mode 100644 posix/tst-spawn5.c create mode 100644 sysdeps/unix/sysv/linux/spawn_int_abi.h -- 2.17.1 diff --git a/posix/Makefile b/posix/Makefile index 8ac6743ad7..1ac41ad85a 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 \ @@ -100,7 +101,8 @@ tests := test-errno tstgetopt testfnm runtests runptests \ tst-posix_fadvise tst-posix_fadvise64 \ 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 + bug-regex38 tst-regcomp-truncated tst-spawn-chdir \ + 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 @@ -254,6 +256,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..c8268e5996 100644 --- a/posix/Versions +++ b/posix/Versions @@ -146,6 +146,7 @@ libc { posix_spawn_file_actions_addfchdir_np; } GLIBC_2.30 { + posix_spawn_file_actions_addclosefrom_np; } GLIBC_PRIVATE { __libc_fork; __libc_pread; __libc_pwrite; diff --git a/posix/spawn.h b/posix/spawn.h index 471dbea022..773f416b2e 100644 --- a/posix/spawn.h +++ b/posix/spawn.h @@ -213,6 +213,13 @@ 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..52e949c8b3 --- /dev/null +++ b/posix/spawn_faction_addclosefrom.c @@ -0,0 +1,58 @@ +/* Add a closefrom to a file action list for posix_spawn. + Copyright (C) 2019 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 (fd < 0) + 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 + __set_errno (EINVAL); + return -1; +#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 51fab13585..b45d1cd889 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 93b7597f90..0bc29226e4 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/spawn_int_abi.h b/posix/spawn_int_abi.h new file mode 100644 index 0000000000..142efed339 --- /dev/null +++ b/posix/spawn_int_abi.h @@ -0,0 +1,27 @@ +/* Internal ABI specific for posix_spawn functionality. Generic version. + Copyright (C) 2019 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 + +/* The closefrom file actions requires either a syscall or an arch-specific + way to interact over all file descriptors and act uppon them (such + /proc/self/fd on Linux). */ +#define __SPAWN_SUPPOR_CLOSEFROM 0 + +#endif /* _SPAWN_INT_H */ diff --git a/posix/tst-spawn5.c b/posix/tst-spawn5.c new file mode 100644 index 0000000000..7af33a4dbe --- /dev/null +++ b/posix/tst-spawn5.c @@ -0,0 +1,210 @@ +/* Tests for posix_spawn signal handling. + Copyright (C) 2019 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 + +/* Nonzero if the program gets called via `exec'. */ +static int restart; +#define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +/* Called on process re-execution. */ +static int +handle_restart (int from) +{ + DIR *fds = opendir ("/proc/self/fd"); + if (fds == NULL) + FAIL_EXIT1 ("opendir (\"/proc/self/fd\"): %m"); + + while (true) + { + errno = 0; + struct dirent64 *e = readdir64 (fds); + 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 (fds)) + continue; + + struct stat64 st; + if (fstat64 (fd, &st) != 0) + FAIL_EXIT1 ("readdir: fstat64 (%ld) failed: %m", fd); + + if (fd >= from) + FAIL_EXIT1 ("error: fd (%ld) greater than from (%d)", fd, from); + } + + closedir (fds); + + return 0; +} + +/* Common argument used for process re-execution. */ +static char *initial_spargv[5]; +static size_t initial_spargv_size; + +/* Re-execute the test process with both '--direct', '--restart', and the + TEST (as integer value) as arguments. */ +static void +reexecute (int fd, const posix_spawn_file_actions_t *fa) +{ + char *spargv[8]; + int i; + + for (i = 0; i < initial_spargv_size; i++) + spargv[i] = initial_spargv[i]; + /* Three digits per byte plus null terminator. */ + char teststr[3 * sizeof (fd) + 1]; + snprintf (teststr, array_length (teststr), "%d", fd); + spargv[i++] = teststr; + spargv[i] = NULL; + TEST_VERIFY (i < 8); + + pid_t pid; + int status; + + TEST_COMPARE (posix_spawn (&pid, spargv[0], fa, NULL, spargv, 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 (int num_fd_to_open) +{ + int *fds = xmalloc (num_fd_to_open * sizeof (int)); + for (int i = 0; i < num_fd_to_open; i++) + fds[i] = xopen ("/dev/null", O_WRONLY, 0); + + posix_spawn_file_actions_t fa; + /* posix_spawn_file_actions_init does not fail. */ + posix_spawn_file_actions_init (&fa); + + { + int ret = posix_spawn_file_actions_addclosefrom_np (&fa, fds[0]); + if (ret == -1) + { + if (errno == ENOSYS) + /* Hurd currently does not support closefrom fileaction. */ + FAIL_UNSUPPORTED ("posix_spawn_file_actions_addclosefrom_np unsupported"); + else + FAIL_EXIT1 ("posix_spawn_file_actions_addclosefrom_np failed"); + } + } + + /* Default check, all file descriptor from [fd[0], fd[1]) are opened. */ + reexecute (fds[0], &fa); + + /* Add a gap in the range. */ + xclose (fds[num_fd_to_open/2]); + xclose (fds[num_fd_to_open/2 + 1]); + reexecute (fds[0], &fa); + + /* Add another gap, at the beginning. */ + xclose (fds[0]); + xclose (fds[1]); + reexecute (fds[0], &fa); + + /* Add another gap, now at the end. */ + xclose (fds[num_fd_to_open-1]); + xclose (fds[num_fd_to_open-2]); + reexecute (fds[0], &fa); + + /* Open some more files, filling the gaps. */ + for (int i = 0; i < 6; i++) + xopen ("/dev/null", O_WRONLY, 0); + reexecute (fds[0], &fa); + + /* Open some more, but with O_CLOEXEC. */ + for (int i = 0; i < num_fd_to_open/2; i++) + xopen ("/dev/null", O_WRONLY | O_CLOEXEC, 0); + + free (fds); +} + + +static int +do_test (int argc, char *argv[]) +{ + /* We must have one or four parameters left if called initially: + + path for ld.so optional + + "--library-path" optional + + the library path optional + + the application name + + Plus one parameter to indicate which test to execute through + re-execution. + + So for default usage without --enable-hardcoded-path-in-tests, it + will be called initially with 5 arguments and later with 2. For + --enable-hardcoded-path-in-tests it will be called with 2 arguments + regardless. */ + + if (argc != (restart ? 2 : 5) && argc != 2) + FAIL_EXIT1 ("wrong number of arguments (%d)", argc); + + if (restart) + return handle_restart (atoi (argv[1])); + + /* Respawn using the same arguments. */ + for (initial_spargv_size = 0; + initial_spargv_size < (argc == 5 ? 4 : 1); + initial_spargv_size++) + initial_spargv[initial_spargv_size] = argv[initial_spargv_size + 1]; + initial_spargv[initial_spargv_size++] = (char *) "--direct"; + initial_spargv[initial_spargv_size++] = (char *) "--restart"; + + do_test_closefrom (10); + do_test_closefrom (100); + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index 1fc7ab2433..fcf957cfc6 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2175,6 +2175,7 @@ GLIBC_2.3.4 setipv4sourcefilter F GLIBC_2.3.4 setsourcefilter F GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 twalk_r F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c index e8024a2679..720e56ffb3 100644 --- a/sysdeps/mach/hurd/spawni.c +++ b/sysdeps/mach/hurd/spawni.c @@ -597,6 +597,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 a5913feb14..3beaba91db 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 a4c31932cb..e1e793b348 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2143,5 +2143,6 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index fe85a35620..735e54f433 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2218,6 +2218,7 @@ GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist index bc3df8dcea..a3b9db6efa 100644 --- a/sysdeps/unix/sysv/linux/arm/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist @@ -128,6 +128,7 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 9b3cee65bb..88d112b9b1 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2087,5 +2087,6 @@ GLIBC_2.29 xprt_register F GLIBC_2.29 xprt_unregister F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 75edece94a..2925c96183 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2039,6 +2039,7 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 edeaf8e722..9fd8ceb639 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2205,6 +2205,7 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 b5d460eeb2..37d817eeb3 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2071,6 +2071,7 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 05633b3cb8..e81ab1f0bf 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -129,6 +129,7 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 47eb7b4608..cd5742bf63 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2148,6 +2148,7 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist index f7ced487f7..957b14d992 100644 --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist @@ -2135,5 +2135,6 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index e49dc4272e..b8ffdea448 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2122,6 +2122,7 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 daa3b60c5b..e1c861720a 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2120,6 +2120,7 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 457ce0b6f2..88fe3f4d26 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2128,6 +2128,7 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 63d5c03bfb..7c6dafa818 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2122,6 +2122,7 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 7fec0c9670..487b005070 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2176,5 +2176,6 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 9200a54309..db81db978a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2178,6 +2178,7 @@ GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 2860df8ebc..06dfdf1fed 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2041,6 +2041,7 @@ GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 2229a1dcc0..eb0532937e 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2245,5 +2245,6 @@ GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 31010e6cf7..4985fa93e3 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2105,5 +2105,6 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 576295deff..1ef1b9d4cc 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2173,6 +2173,7 @@ GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 abf0473683..f9d9fe68ca 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2077,6 +2077,7 @@ GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist index 41977f6e9c..1b12384dd1 100644 --- a/sysdeps/unix/sysv/linux/sh/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist @@ -2043,6 +2043,7 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 3d2f00ca52..a7c244cb56 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2167,6 +2167,7 @@ GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 2f20643e8e..a71facfb43 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2094,6 +2094,7 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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..9c4b31ccae --- /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) 2019 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 c1abf3f960..ca7bf99825 100644 --- a/sysdeps/unix/sysv/linux/spawni.c +++ b/sysdeps/unix/sysv/linux/spawni.c @@ -17,20 +17,16 @@ . */ #include -#include #include -#include +#include #include -#include -#include -#include #include #include #include -#include -#include -#include +#include +#include #include +#include #include "spawn_int.h" /* The Linux implementation of posix_spawn{p} uses the clone syscall directly @@ -114,6 +110,44 @@ maybe_script_execute (struct posix_spawn_args *args) } } +/* Close all file descriptor up to FROM by interacting /proc/self/fd. */ +static bool +spawn_closefrom (int from) +{ + struct dirent64 entries[1024 / sizeof (struct dirent64)]; + + int dirfd = __open ("/proc/self/fd", O_RDONLY | O_DIRECTORY, 0); + if (dirfd == -1) + return false; + + ssize_t r; + while ((r = __getdents64 (dirfd, entries, sizeof (entries))) > 0) + { + struct dirent64 *dp = entries; + struct dirent64 *edp = (void *)((uintptr_t) dp + r); + + for (struct dirent64 *dp = entries; dp < edp; + dp = (void *)((uintptr_t) dp + dp->d_reclen)) + { + int fd = 0; + + if (dp->d_name[0] == '.') + continue; + + for (const char *s = dp->d_name; isdigit (*s); s++) + fd = 10 * fd + (*s - '0'); + + if (fd == dirfd || fd < from) + continue; + + __close_nocancel (fd); + } + } + + __close_nocancel (dirfd); + return true; +} + /* Function used in the clone call to setup the signals mask, posix_spawn attributes, and file actions. It run on its own stack (provided by the posix_spawn call). */ @@ -280,6 +314,11 @@ __spawni_child (void *arguments) if (__fchdir (action->action.fchdir_action.fd) != 0) goto fail; break; + + case spawn_do_closefrom: + if (!spawn_closefrom (action->action.closefrom_action.from)) + goto fail; + break; } } } @@ -339,12 +378,13 @@ __spawnix (pid_t * pid, const char *file, int prot = (PROT_READ | PROT_WRITE | ((GL (dl_stack_flags) & PF_X) ? PROT_EXEC : 0)); - /* Add a slack area for child's stack. */ - size_t argv_size = (argc * sizeof (void *)) + 512; + size_t argv_size = (argc * sizeof (void *)); /* 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 59f85d9373..78a43f5851 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2052,6 +2052,7 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r 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 67a4e238d6..b83897ddbf 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2151,5 +2151,6 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 posix_spawn_file_actions_addclosefrom_np F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F