From patchwork Wed May 17 17:35:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1782819 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=JF9s4LtB; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QM0cv3GD0z20KF for ; Thu, 18 May 2023 03:35:43 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5D416385B50D for ; Wed, 17 May 2023 17:35:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5D416385B50D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1684344941; bh=ed07cc1FPNDJV2d7joCqI+2djT6w/gI4cAFm3RfgSj4=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=JF9s4LtBoLknSqSqLJSo/Q90WkoOV+trxnAmpt79Qut2QH7g0iZo6W+UwR/Jdb2+T GlOhbTyPVO12fuG2+S1DRtNQrT3vLdnrRm2LZba1Dh38doLLa1TaHfJQ3b5Q73SUom GcDBzE10G5OneKPYKlXhovRoQ/s8LmL8jenEyAYA= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ot1-x332.google.com (mail-ot1-x332.google.com [IPv6:2607:f8b0:4864:20::332]) by sourceware.org (Postfix) with ESMTPS id 126BA3858C41 for ; Wed, 17 May 2023 17:35:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 126BA3858C41 Received: by mail-ot1-x332.google.com with SMTP id 46e09a7af769-6ab0967093dso815258a34.3 for ; Wed, 17 May 2023 10:35:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684344922; x=1686936922; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ed07cc1FPNDJV2d7joCqI+2djT6w/gI4cAFm3RfgSj4=; b=V8zbtEsP18XVO5Rk2zw7S60g4+U1dRY2b4qewlCx3/DGY+MEqtop3YF+gJLt8+btgY OCJFkkNKeZJHONCdBY+G0tFJkblGczuFu354exeQmfy3RggTpCgqTCthLaclKU0YHhNZ ggO+yt9CGVHdLrveoqbUZzWh3D4nTyPkFPkrQNfDivGntFMt1PEyA8s4sa8PjFU7ERqY ahdFusj1II306WeHq9YyuLF+Bds5LXjqSpC9nBXF5ZXcXQPV1UTwQttGNNkahG6rO3pV EgLpWGvLHiV7ySrp0BHBJO5y6QOonjyR6AcE0hlAgZcnbMlFlJ8NrBEYlbbpQJEBtCl0 zhHw== X-Gm-Message-State: AC+VfDzWFG/UUS9W6P2TMrV99dBkLrF99jgsOElqfVSRyyeHienHlim6 HhDJUc2aTPmsHXa0ueVqHEIdcD/jEvYlgcI6gBbK/g== X-Google-Smtp-Source: ACHHUZ6ts4ER6VlRei9IdrerS33PoFvtT3gTpIcVn5hHJXDQH6+Pj8iI73y+ilcFvKC+YrjzAKLMqw== X-Received: by 2002:a05:6870:a89a:b0:19a:1a4d:87e3 with SMTP id eb26-20020a056870a89a00b0019a1a4d87e3mr1106623oab.48.1684344921785; Wed, 17 May 2023 10:35:21 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c0:c914:7221:bfda:36ba:bc70]) by smtp.gmail.com with ESMTPSA id eb20-20020a056870a89400b00172428894e0sm14256334oab.28.2023.05.17.10.35.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 May 2023 10:35:20 -0700 (PDT) To: libc-alpha@sourceware.org, Luca Boccassi , Florian Weimer , Philip Withnall Subject: [PATCH v4 0/3] Add pidfd_spawn, pidfd_spawnp, pidfd_fork, and pidfd_getpid Date: Wed, 17 May 2023 14:35:13 -0300 Message-Id: <20230517173516.1988283-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Spam-Status: No, score=-5.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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 Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" The glibc 2.36 added wrappers for Linux syscall pidfd_open, pidfd_getfd, and pidfd_send_signal, and exported the P_PIDFD to use along with waitid. However, although the pidfd is a race free interface, the pidfd_open is subject to TOCTOU if the file descriptor is not obtained directly from the clone or clone3 syscall (there is still a small window between the clone return and the pidfd_getfd where the process can be reaped and the process ID reused). A fully race free interface with posix_spawn interface is being discussed by GNOME [1] [2], and Qt already uses on its QtProcess implementation [3]. The Qt implementation has some pitfalls: - It calls clone through the syscall symbol, which does not run the pthread_atfork handlers even though it really intends to use the clone semantic for fork (by only using CLONE_PIDFD | SIGCHLD). - It also does not reset any internal state, such as internal IO, malloc, loader, etc. locks. - It does not set the TCB tid field nor the robust list, used by pthread code. - It does not optimize process creation by using CLONE_VM and CLONE_VFORK. This patchset adds new interfaces that take care of this potential issues. The pidfd_spawn and pidfd_spawnp handles all these cases by using the same internal implementation used by posix_spawn: int pidfd_spawn (int *restrict pidfd, const char *restrict file, const posix_spawn_file_actions_t *restrict facts, const posix_spawnattr_t *restrict attrp, char *const argv[restrict], char *const envp[restrict]) int pidfd_spawnp (int *restrict pidfd, const char *restrict path, const posix_spawn_file_actions_t *restrict facts, const posix_spawnattr_t *restrict attrp, char *const argv[restrict_arr], char *const envp[restrict_arr]); The implementation makes sure that kernel must support the complete pidfd interface, meaning that waitid (P_PIDFD) should be supported. It ensure that non racy workaround is required (such as reading procfs fdinfo pid to use along with old wait interfaces). If kernel does not have the required support the interface returns ENOSYS. A new symbol is used instead of a posix_spawn extension to avoid possible issue with language bindings that might track the argument lifetime. Both symbols reuse the posix_spawn posix_spawn_file_actions_t and posix_spawnattr_t, to either avoid rehash posix_spawn API or add a new one. It also mean that both interfaces support the same attribute and file actions, and a new flag or file actions on posix_spawn is also added automatically for pidfd_spawn. Along with the spawn interface, a fork like one is also provided: int pidfd_fork (unsigned int flags) The kernel already sets O_CLOEXEC as default and it follow fork/_Fork convention on returning a positive or negative value to the parent (with negative indicating an error) and zero to the child. Similar to fork, pidfd_fork also run the handler setup by pthread_atfork and reset some internal libc state. It can be changed by using the PIDFDFORK_ASYNCSAFE, where pidfd_fork acts as _Fork. To have a way to interop between process IDs and process file descriptors, the pidfd_getpid is also provided. It just read the procps fdinfo entry from the file descriptor to get the process ID. --- Changes from v3: - Remove strtoul usage. - Fixed patchwork tst-pidfd_getpid.c regression. - Fixed manual and NEWS typos. Changes from v2: - Added pidfd_fork and pidfd_getpid manual entries - Change pidfd_fork to act as fork as default, instead as _Fork. - Changed PIDFD_FORK_RUNATFORK flag to PIDFDFORK_ASYNCSAFE. - Added pidfd_getpid test for EREMOTE. Changes from v1: - Extended pidfd_getpid error codes to return EBADF if fdinfo does not have Pid entry or if the value is invalid, EREMOTE is pid is in a separate namespace, and ESRCH if is already terminated. - Extended tst-pidfd_getpid. - Rename PIDFD_FORK_RUNATFORK to PIDFDFORK_RUNATFORK to avoid clash with possible kernel extensions. Adhemerval Zanella (3): posix: Add pidfd_spawn and pidfd_spawnp (BZ# 30349) posix: Add pidfd_fork linux: Add pidfd_getpid NEWS | 16 ++ bits/spawn_ext.h | 21 ++ include/clone_internal.h | 4 + manual/process.texi | 82 ++++++-- posix/Makefile | 5 +- posix/fork-internal.c | 125 ++++++++++++ posix/fork-internal.h | 29 +++ posix/fork.c | 98 +--------- posix/spawn.h | 2 + posix/spawn_int.h | 3 +- posix/tst-posix_spawn-setsid.c | 168 +++++++++++----- posix/tst-spawn-chdir.c | 15 +- posix/tst-spawn.c | 24 +-- posix/tst-spawn.h | 36 ++++ posix/tst-spawn2.c | 17 +- posix/tst-spawn3.c | 100 +++++----- posix/tst-spawn4.c | 7 +- posix/tst-spawn5.c | 14 +- posix/tst-spawn6.c | 15 +- posix/tst-spawn7.c | 13 +- sysdeps/nptl/_Fork.c | 2 +- sysdeps/unix/sysv/linux/Makefile | 26 +++ sysdeps/unix/sysv/linux/Versions | 6 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 4 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 4 + sysdeps/unix/sysv/linux/arc/libc.abilist | 4 + sysdeps/unix/sysv/linux/arch-fork.h | 16 +- sysdeps/unix/sysv/linux/arm/be/libc.abilist | 4 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 4 + sysdeps/unix/sysv/linux/bits/spawn_ext.h | 45 +++++ sysdeps/unix/sysv/linux/clone-pidfd-support.c | 58 ++++++ sysdeps/unix/sysv/linux/csky/libc.abilist | 4 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 4 + sysdeps/unix/sysv/linux/i386/libc.abilist | 4 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 4 + .../sysv/linux/loongarch/lp64/libc.abilist | 4 + .../sysv/linux/m68k/coldfire/libc.abilist | 4 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 4 + .../sysv/linux/microblaze/be/libc.abilist | 4 + .../sysv/linux/microblaze/le/libc.abilist | 4 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 4 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 4 + .../sysv/linux/mips/mips64/n32/libc.abilist | 4 + .../sysv/linux/mips/mips64/n64/libc.abilist | 4 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 4 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 4 + sysdeps/unix/sysv/linux/pidfd_fork.c | 76 ++++++++ sysdeps/unix/sysv/linux/pidfd_getpid.c | 122 ++++++++++++ sysdeps/unix/sysv/linux/pidfd_spawn.c | 30 +++ sysdeps/unix/sysv/linux/pidfd_spawnp.c | 30 +++ .../linux/powerpc/powerpc32/fpu/libc.abilist | 4 + .../powerpc/powerpc32/nofpu/libc.abilist | 4 + .../linux/powerpc/powerpc64/be/libc.abilist | 4 + .../linux/powerpc/powerpc64/le/libc.abilist | 4 + sysdeps/unix/sysv/linux/procutils.c | 104 ++++++++++ sysdeps/unix/sysv/linux/procutils.h | 35 ++++ .../unix/sysv/linux/riscv/rv32/libc.abilist | 4 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 4 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 4 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 4 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 4 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 4 + .../sysv/linux/sparc/sparc32/libc.abilist | 4 + .../sysv/linux/sparc/sparc64/libc.abilist | 4 + sysdeps/unix/sysv/linux/spawni.c | 20 +- sysdeps/unix/sysv/linux/sys/pidfd.h | 17 ++ sysdeps/unix/sysv/linux/tst-pidfd.c | 45 +++++ sysdeps/unix/sysv/linux/tst-pidfd_fork.c | 150 +++++++++++++++ sysdeps/unix/sysv/linux/tst-pidfd_getpid.c | 181 ++++++++++++++++++ .../sysv/linux/tst-posix_spawn-setsid-pidfd.c | 20 ++ .../unix/sysv/linux/tst-spawn-chdir-pidfd.c | 20 ++ sysdeps/unix/sysv/linux/tst-spawn-pidfd.c | 20 ++ sysdeps/unix/sysv/linux/tst-spawn-pidfd.h | 63 ++++++ sysdeps/unix/sysv/linux/tst-spawn2-pidfd.c | 20 ++ sysdeps/unix/sysv/linux/tst-spawn3-pidfd.c | 20 ++ sysdeps/unix/sysv/linux/tst-spawn4-pidfd.c | 20 ++ sysdeps/unix/sysv/linux/tst-spawn5-pidfd.c | 20 ++ sysdeps/unix/sysv/linux/tst-spawn6-pidfd.c | 20 ++ sysdeps/unix/sysv/linux/tst-spawn7-pidfd.c | 20 ++ .../unix/sysv/linux/x86_64/64/libc.abilist | 4 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 4 + 81 files changed, 1877 insertions(+), 259 deletions(-) create mode 100644 bits/spawn_ext.h create mode 100644 posix/fork-internal.c create mode 100644 posix/fork-internal.h create mode 100644 posix/tst-spawn.h create mode 100644 sysdeps/unix/sysv/linux/bits/spawn_ext.h create mode 100644 sysdeps/unix/sysv/linux/clone-pidfd-support.c create mode 100644 sysdeps/unix/sysv/linux/pidfd_fork.c create mode 100644 sysdeps/unix/sysv/linux/pidfd_getpid.c create mode 100644 sysdeps/unix/sysv/linux/pidfd_spawn.c create mode 100644 sysdeps/unix/sysv/linux/pidfd_spawnp.c create mode 100644 sysdeps/unix/sysv/linux/procutils.c create mode 100644 sysdeps/unix/sysv/linux/procutils.h create mode 100644 sysdeps/unix/sysv/linux/tst-pidfd_fork.c create mode 100644 sysdeps/unix/sysv/linux/tst-pidfd_getpid.c create mode 100644 sysdeps/unix/sysv/linux/tst-posix_spawn-setsid-pidfd.c create mode 100644 sysdeps/unix/sysv/linux/tst-spawn-chdir-pidfd.c create mode 100644 sysdeps/unix/sysv/linux/tst-spawn-pidfd.c create mode 100644 sysdeps/unix/sysv/linux/tst-spawn-pidfd.h create mode 100644 sysdeps/unix/sysv/linux/tst-spawn2-pidfd.c create mode 100644 sysdeps/unix/sysv/linux/tst-spawn3-pidfd.c create mode 100644 sysdeps/unix/sysv/linux/tst-spawn4-pidfd.c create mode 100644 sysdeps/unix/sysv/linux/tst-spawn5-pidfd.c create mode 100644 sysdeps/unix/sysv/linux/tst-spawn6-pidfd.c create mode 100644 sysdeps/unix/sysv/linux/tst-spawn7-pidfd.c