From patchwork Tue May 10 19:11:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1629330 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=xCCHN6tc; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KySNs0NQJz9sG6 for ; Wed, 11 May 2022 05:13:00 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E1B7938425B5 for ; Tue, 10 May 2022 19:12:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E1B7938425B5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1652209977; bh=jQukY1ij2oWhH81JcSQoAkNK+V8jiB64+wISvoBAKAg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=xCCHN6tcYUZw+mntOTuPgKXRmwHlt5yXBjL17hjgeyezrs1lqquZ0W4woqBl9PvSU /cyU3Fy+slatABSO6bOR8sqPrZmpbGigzydEVwAM3JXjnLPJnSMOHPuE8mhvp0yuxE oNZmmY8M8NXY2rFP2j0m2zAmL+a80oHSq+e2UDLo= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-oo1-xc2b.google.com (mail-oo1-xc2b.google.com [IPv6:2607:f8b0:4864:20::c2b]) by sourceware.org (Postfix) with ESMTPS id 15EAE385380D for ; Tue, 10 May 2022 19:12:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 15EAE385380D Received: by mail-oo1-xc2b.google.com with SMTP id f2-20020a4a8f42000000b0035e74942d42so3654588ool.13 for ; Tue, 10 May 2022 12:12:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jQukY1ij2oWhH81JcSQoAkNK+V8jiB64+wISvoBAKAg=; b=d8RyCaU1kPFj9aDm24cWIJciJ0/44rss9Mev9ePDBBZS2gFdEVt1MCsfDkIh5bOLAH DWDWADPjyyU8ORJZ0/PCqkraEdjaJqbf6FcP8jm7klFtCroYLLGzlu1n0oSWNXUpB7xw kDGbPl2o/yN1qUz8RnJClltzYvyu3VsiuYne55SqvRe+KZZa2K+cxxt39W5RSGTx6xgn d0tFnIT9EU8Fzrc0wDblQYSi0gbifuVrEsrs18+5vo2LvFMhs4wnJgUYuR6V3NSTFl8N LWJkytS6L88xh0XwQTL8wCZokgB096GSEsj5oSrLq0X1ckohmiIPLAC5nBPSmsEA4yUa ZdBg== X-Gm-Message-State: AOAM530LLgheCnXoKt54iEu3ukHqDV0IvDu4RpCqT6uJoWnuC85S3/P3 Jok4K0ZrHyZhwr2Rg4CjuhXJ1KGP6dTjYg== X-Google-Smtp-Source: ABdhPJwrlyeaulW3+7UJJIY1CGfednT6PK+Dq5pPV3j182izV75KZeo0QCnm8KvS+yU9usPDTm9+ZQ== X-Received: by 2002:a05:6820:35a:b0:35e:ae97:1124 with SMTP id m26-20020a056820035a00b0035eae971124mr8590343ooe.66.1652209922133; Tue, 10 May 2022 12:12:02 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:5fbd:76f7:9485:c71c:cb46]) by smtp.gmail.com with ESMTPSA id a204-20020acab1d5000000b00325643bce40sm5792390oif.0.2022.05.10.12.12.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 May 2022 12:12:01 -0700 (PDT) To: libc-alpha@sourceware.org, Alexey Izbyshev , Carlos O'Donell , Florian Weimer Subject: [PATCH v4 1/3] linux: Add CLONE_NEWTIME from Linux 5.6 to bits/sched.h Date: Tue, 10 May 2022 16:11:53 -0300 Message-Id: <20220510191155.1998575-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220510191155.1998575-1-adhemerval.zanella@linaro.org> References: <20220510191155.1998575-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" It was added in commit 769071ac9f20b6a447410c7eaa55d1a5233ef40c. --- sysdeps/unix/sysv/linux/bits/sched.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sysdeps/unix/sysv/linux/bits/sched.h b/sysdeps/unix/sysv/linux/bits/sched.h index f13c569863..d79359eaeb 100644 --- a/sysdeps/unix/sysv/linux/bits/sched.h +++ b/sysdeps/unix/sysv/linux/bits/sched.h @@ -71,6 +71,10 @@ # define CLONE_NEWPID 0x20000000 /* New pid namespace. */ # define CLONE_NEWNET 0x40000000 /* New network namespace. */ # define CLONE_IO 0x80000000 /* Clone I/O context. */ + +/* cloning flags intersect with CSIGNAL so can be used only with unshare and + clone3 syscalls. */ +#define CLONE_NEWTIME 0x00000080 /* New time namespace */ #endif #include From patchwork Tue May 10 19:11:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1629331 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=LnhCFaJr; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KySPd6MYzz9sG6 for ; Wed, 11 May 2022 05:13:41 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9FD503836016 for ; Tue, 10 May 2022 19:13:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9FD503836016 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1652210019; bh=HmYK5di/sNjCDrubkg4oV0b/G5AshMEzOZqLXdhI0oQ=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=LnhCFaJr8adxSWCZgIU8jY0XJR993WVk45qC4bZ7OM8mrFOJQxV1Lh341CYTWZoQr rWXA/p0R+ptV3DpUFeKhr0k8TU1XxaomJduIQE9FjHgSMeWBzO7VI+/qx7C8oHLMFn GvsCcmKqqfECOlCArz7CaQ2WWdLQxtaqIKAD/2t0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-oa1-x29.google.com (mail-oa1-x29.google.com [IPv6:2001:4860:4864:20::29]) by sourceware.org (Postfix) with ESMTPS id 434C53839802 for ; Tue, 10 May 2022 19:12:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 434C53839802 Received: by mail-oa1-x29.google.com with SMTP id 586e51a60fabf-edeb6c3642so167785fac.3 for ; Tue, 10 May 2022 12:12:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HmYK5di/sNjCDrubkg4oV0b/G5AshMEzOZqLXdhI0oQ=; b=ZZ812L7dCN3+3Wdau3K2p/viPialuyPEqvSHKs6JddlhoICGUJ9MmDDLGfrgSiEqZP zi6TXH0rXcBRbE9PlLNUaBs8/+1hVU837EnR3CMpTAwYqTDDfgyq7BTLR/WD5FstRiFb glsHA0X1f1vhHx+RH/8awrFdiR/FxLjHYfFGyT3+TNKxpcLRqK+a/EGEVW48kHT9rC8f UeBmalLVV5PRl2zPMcYWzue3NwNFMDEWSpCVdu6TJ633GNsOJ8KP+RMWQPtt4xr6suje c+5MQhAQK58F5p+pfmw78N+m7C86UkuMday23hY+WgBto7A+gjkH8TVbVpBTCjL17kB8 zr5w== X-Gm-Message-State: AOAM532RKT6X1xV1ZSpzXUi2tpEee3UKOmqdXRaXzy90IGaieRJQuMDS UJkP8juWKpZVofxo71mtN2xjVH7P6TEwSw== X-Google-Smtp-Source: ABdhPJx6KsqxKHah41NgHJip+ANhHEh828P9frHTyu4gstO7aTVfzi9Ey5ZUPkhJvIqthrZBiMnmtg== X-Received: by 2002:a05:6870:b012:b0:ed:f22e:8aa4 with SMTP id y18-20020a056870b01200b000edf22e8aa4mr903914oae.59.1652209924383; Tue, 10 May 2022 12:12:04 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:5fbd:76f7:9485:c71c:cb46]) by smtp.gmail.com with ESMTPSA id a204-20020acab1d5000000b00325643bce40sm5792390oif.0.2022.05.10.12.12.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 May 2022 12:12:03 -0700 (PDT) To: libc-alpha@sourceware.org, Alexey Izbyshev , Carlos O'Donell , Florian Weimer Subject: [PATCH v4 2/3] support: Add support_enter_time_namespace Date: Tue, 10 May 2022 16:11:54 -0300 Message-Id: <20220510191155.1998575-3-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220510191155.1998575-1-adhemerval.zanella@linaro.org> References: <20220510191155.1998575-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 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, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Enter a time namespace, where the new namespace isolates clock values. It requires either a root-like privileges (done with support_become_root) or a previous user namespace (CLONE_NEWUSER). A time namespace is similar to a pid namespace in the way how it is created: unshare(CLONE_NEWTIME) system call creates a new time namespace, but doesn't set it to the current process. Then all children of the process will be born in the new time namespace. It will be used on posix_spawn tests to exercise the BZ #29115 fix, where clone (CLONE_VFORK | CLONE_VM) fails if the process enter a time namespace. --- support/Makefile | 1 + support/namespace.h | 5 ++++ support/support_enter_time_namespace.c | 34 ++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 support/support_enter_time_namespace.c diff --git a/support/Makefile b/support/Makefile index 9b50eac117..e4a1402c36 100644 --- a/support/Makefile +++ b/support/Makefile @@ -56,6 +56,7 @@ libsupport-routines = \ support_descriptors \ support_enter_mount_namespace \ support_enter_network_namespace \ + support_enter_time_namespace \ support_format_address_family \ support_format_addrinfo \ support_format_dns_packet \ diff --git a/support/namespace.h b/support/namespace.h index 23bad6403b..338000547c 100644 --- a/support/namespace.h +++ b/support/namespace.h @@ -56,6 +56,11 @@ bool support_enter_network_namespace (void); not affect the host system afterwards. */ bool support_enter_mount_namespace (void); +/* Enter a time namespace, where the new namespace isolates clock + values. It requires either a root-like privileges (done with + support_become_root) or a previous user namespace (CLONE_NEWUSER). */ +bool support_enter_time_namespace (void); + /* Return true if support_enter_network_namespace managed to enter a UTS namespace. */ bool support_in_uts_namespace (void); diff --git a/support/support_enter_time_namespace.c b/support/support_enter_time_namespace.c new file mode 100644 index 0000000000..a18caa878a --- /dev/null +++ b/support/support_enter_time_namespace.c @@ -0,0 +1,34 @@ +/* Enter a time namespace. + Copyright (C) 2022 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 + +bool +support_enter_time_namespace (void) +{ +#ifdef CLONE_NEWTIME + if (unshare (CLONE_NEWTIME) == 0) + return true; + else + printf ("warning: unshare (CLONE_NEWTIME) failed: %m\n"); +#endif /* CLONE_NEWNS */ + return false; +} From patchwork Tue May 10 19:11:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1629332 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=UYb82iQm; dkim-atps=neutral Authentication-Results: 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=) 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 RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KySQS1ysVz9sG6 for ; Wed, 11 May 2022 05:14:24 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 099FF3838024 for ; Tue, 10 May 2022 19:14:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 099FF3838024 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1652210062; bh=BklQ0tujDAVp18TvVPxC3aMwmjoTIuwVMp2xXcvxtRY=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=UYb82iQm+jvwNbXTnLQT7s2x1ra2TDmHw9rAUHM3pHS+5PYJhCAMUlut3A6yEKzuL 1GVNktKAjFkrIM5i3XH3a7N91duPSh1vweySeRgi7GGQikNUmhtO5aLH6qFlnx2Y1A TcRpwOV8SLXrmA+urZ8V1Y84ywBFGQo3ch6tR9hU= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-oa1-x29.google.com (mail-oa1-x29.google.com [IPv6:2001:4860:4864:20::29]) by sourceware.org (Postfix) with ESMTPS id E02663839423 for ; Tue, 10 May 2022 19:12:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E02663839423 Received: by mail-oa1-x29.google.com with SMTP id 586e51a60fabf-d6e29fb3d7so144661fac.7 for ; Tue, 10 May 2022 12:12:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BklQ0tujDAVp18TvVPxC3aMwmjoTIuwVMp2xXcvxtRY=; b=3NxNemVzdpN6kTrXItLNtmrStPtm994t35phKkv+8xrdB4TFlnGTmX59gpNk+9M0Yn umS8HdrcNb3E4j9vbooAwBtSmRmsP5KNCVxFFT+ra/8PuDNKoSimd45WCfmzPOhOqdoT gzFzVrEN8DMWSGE3S+wgkQCkmimWHaXHaVnGFtLEdA4zf531H6r0Cp9Di8sFxSRROTAZ /AVnlamR1e3fmv1TPO4qVDeReScS0YadPvDL6JN612qpUu0ByTMcnOctwD44UaWVfNZp UtR1HULIDZqWJnT1zGRLbDSmdojensAmKP8EPDvYvHVktMCTEKEdgR4Df1ArCofHxgHO nHlw== X-Gm-Message-State: AOAM531WZJ3VHyE12+uEAzzytVwKqTypRvj1hLZwkzXv1SOH3i/MkQbR vMGjYLGtKFyTkNX8K83gItfVm58P1qeQBQ== X-Google-Smtp-Source: ABdhPJy6nDEtBS7crNgJzt2b/lYHfjcRS+t/Bx0woc6kT4QRa4pGxZuduZP7c2POK8aYQH5T1GJVbA== X-Received: by 2002:a05:6870:4610:b0:e9:a4a0:84 with SMTP id z16-20020a056870461000b000e9a4a00084mr937364oao.76.1652209926591; Tue, 10 May 2022 12:12:06 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:5fbd:76f7:9485:c71c:cb46]) by smtp.gmail.com with ESMTPSA id a204-20020acab1d5000000b00325643bce40sm5792390oif.0.2022.05.10.12.12.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 May 2022 12:12:05 -0700 (PDT) To: libc-alpha@sourceware.org, Alexey Izbyshev , Carlos O'Donell , Florian Weimer Subject: [PATCH v4 3/3] linux: Add fallback for clone failure on posix_spawn (BZ #29115) Date: Tue, 10 May 2022 16:11:55 -0300 Message-Id: <20220510191155.1998575-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220510191155.1998575-1-adhemerval.zanella@linaro.org> References: <20220510191155.1998575-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Linux clone with CLONE_VM may fail for some namespace restriction (for instance if kernel does not allow processes in different time namespaces to share the sameaddress space). In this case clone fails with EINVAL and posix_spawn can not spawn a new process. However the same process can be spawned with fork and exec. The patch fixes by retrying the clone syscall with just CLONE_VFORK if clone fails with a non transient failure (ENOMEM and EAGAIN still returns failure to caller). Error on preparation phase or execve is returned by a pipe now that there is no shared memory that ca be used. It requires some extra care for some file operations: * If the file operation would clobber the pipe file descriptor, the helper process dup the pipe onto an unoccupied file descriptor. * dup2 file action that targets the pipe file descriptor returns EBADF. * If closefrom argument overlaps the pipe file descriptor, it is splited in two calls: [lowdp, pipe - 1] and [pipe + 1, ~Ou]. Failure on prepare phase in helper process does not trigger the fork and exec fallback. Some spawn tests were adapted to run inside a created time namespace. Checked on x86_64-linux-gnu. --- include/unistd.h | 4 +- io/closefrom.c | 2 +- posix/Makefile | 16 +- posix/tst-spawn-chdir-timens.c | 2 + posix/tst-spawn-chdir.c | 8 + posix/tst-spawn-timens.c | 2 + posix/tst-spawn.c | 6 + posix/tst-spawn2-timens.c | 2 + posix/tst-spawn2.c | 8 + posix/tst-spawn4-timens.c | 2 + posix/tst-spawn4.c | 10 +- posix/tst-spawn5-timens.c | 2 + posix/tst-spawn5.c | 10 +- posix/tst-spawn6-timens.c | 2 + posix/tst-spawn6.c | 12 +- sysdeps/unix/sysv/linux/closefrom_fallback.c | 6 +- sysdeps/unix/sysv/linux/spawni.c | 233 +++++++++++++++---- 17 files changed, 271 insertions(+), 56 deletions(-) create mode 100644 posix/tst-spawn-chdir-timens.c create mode 100644 posix/tst-spawn-timens.c create mode 100644 posix/tst-spawn2-timens.c create mode 100644 posix/tst-spawn4-timens.c create mode 100644 posix/tst-spawn5-timens.c create mode 100644 posix/tst-spawn6-timens.c diff --git a/include/unistd.h b/include/unistd.h index af795a37c8..2643991a09 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -167,7 +167,9 @@ static inline _Bool __closefrom_fallback (int __lowfd, _Bool dirfd_fallback) return false; } # else -extern _Bool __closefrom_fallback (int __lowfd, _Bool) attribute_hidden; +extern _Bool __closefrom_fallback (unsigned int __from, unsigned int __to, + _Bool) + attribute_hidden; # endif extern ssize_t __read (int __fd, void *__buf, size_t __nbytes); libc_hidden_proto (__read) diff --git a/io/closefrom.c b/io/closefrom.c index 48cac2e3d1..a07de06e9b 100644 --- a/io/closefrom.c +++ b/io/closefrom.c @@ -30,7 +30,7 @@ __closefrom (int lowfd) if (r == 0) return ; - if (!__closefrom_fallback (l, true)) + if (!__closefrom_fallback (l, ~0U, true)) __fortify_fail ("closefrom failed to close a file descriptor"); } weak_alias (__closefrom, closefrom) diff --git a/posix/Makefile b/posix/Makefile index 9b30b53a7c..3597aa354b 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -109,7 +109,9 @@ tests := test-errno tstgetopt testfnm runtests runptests \ tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \ bug-regex38 tst-regcomp-truncated tst-spawn-chdir \ tst-wordexp-nocmd tst-execveat tst-spawn5 \ - tst-sched_getaffinity tst-spawn6 + tst-sched_getaffinity tst-spawn6 \ + tst-spawn-chdir-timens tst-spawn4-timens tst-spawn5-timens \ + tst-spawn6-timens # Test for the glob symbol version that was replaced in glibc 2.27. ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes) @@ -130,7 +132,15 @@ xtests := tst-getaddrinfo4 tst-getaddrinfo5 tst-sched_rr_get_interval xtests-time64 := tst-sched_rr_get_interval-time64 ifeq (yes,$(build-shared)) test-srcs := globtest -tests += wordexp-test tst-exec tst-spawn tst-spawn2 tst-spawn3 +tests += \ + tst-exec \ + tst-spawn \ + tst-spawn-timens \ + tst-spawn2 \ + tst-spawn2-timens \ + tst-spawn3 \ + wordexp-test \ + # tests endif ifeq (yesyes,$(build-shared)$(have-thread-library)) tests += tst-getopt-cancel tst-_Fork @@ -290,7 +300,9 @@ 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-spawn5-timens-ARGS = -- $(host-test-program-cmd) tst-spawn6-ARGS = -- $(host-test-program-cmd) +tst-spawn6-timens-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/tst-spawn-chdir-timens.c b/posix/tst-spawn-chdir-timens.c new file mode 100644 index 0000000000..a659e3201e --- /dev/null +++ b/posix/tst-spawn-chdir-timens.c @@ -0,0 +1,2 @@ +#define CHECK_TIMENAMESPACE +#include "tst-spawn-chdir.c" diff --git a/posix/tst-spawn-chdir.c b/posix/tst-spawn-chdir.c index 18e90c2957..ecb0634816 100644 --- a/posix/tst-spawn-chdir.c +++ b/posix/tst-spawn-chdir.c @@ -29,6 +29,7 @@ #include #include #include +#include #include /* Reads the file at PATH, which must consist of exactly one line. @@ -66,6 +67,7 @@ get_pwd_program (void) FAIL_EXIT1 ("cannot find pwd program"); } + /* Adds chdir operations to ACTIONS, using PATH. If DO_FCHDIR, use the open function and TMPFD to emulate chdir using fchdir. */ static void @@ -87,6 +89,12 @@ add_chdir (posix_spawn_file_actions_t *actions, const char *path, static int do_test (void) { +#ifdef CHECK_TIMENAMESPACE + support_become_root(); + if (!support_enter_time_namespace ()) + return EXIT_UNSUPPORTED; +#endif + /* Directory for temporary file data. Each subtest uses a numeric subdirectory. */ char *directory = support_create_temp_directory ("tst-spawn-chdir-"); diff --git a/posix/tst-spawn-timens.c b/posix/tst-spawn-timens.c new file mode 100644 index 0000000000..a659e3201e --- /dev/null +++ b/posix/tst-spawn-timens.c @@ -0,0 +1,2 @@ +#define CHECK_TIMENAMESPACE +#include "tst-spawn-chdir.c" diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c index e378c72f1b..2007384a90 100644 --- a/posix/tst-spawn.c +++ b/posix/tst-spawn.c @@ -178,6 +178,12 @@ do_test (int argc, char *argv[]) return handle_restart (argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); +#ifdef CHECK_TIMENAMESPACE + support_become_root(); + if (!support_enter_time_namespace ()) + return EXIT_UNSUPPORTED; +#endif + /* Prepare the test. We are creating four files: two which file descriptor will be marked with FD_CLOEXEC, another which is not. */ diff --git a/posix/tst-spawn2-timens.c b/posix/tst-spawn2-timens.c new file mode 100644 index 0000000000..612531fc86 --- /dev/null +++ b/posix/tst-spawn2-timens.c @@ -0,0 +1,2 @@ +#define CHECK_TIMENAMESPACE +#include "tst-spawn2.c" diff --git a/posix/tst-spawn2.c b/posix/tst-spawn2.c index 45ff17f9a7..16fcbe4295 100644 --- a/posix/tst-spawn2.c +++ b/posix/tst-spawn2.c @@ -26,10 +26,18 @@ #include #include +#include +#include int do_test (void) { +#ifdef CHECK_TIMENAMESPACE + support_become_root(); + if (!support_enter_time_namespace ()) + return EXIT_UNSUPPORTED; +#endif + /* Check if posix_spawn correctly returns an error and an invalid pid by trying to spawn an invalid binary. */ diff --git a/posix/tst-spawn4-timens.c b/posix/tst-spawn4-timens.c new file mode 100644 index 0000000000..3f4e8ea089 --- /dev/null +++ b/posix/tst-spawn4-timens.c @@ -0,0 +1,2 @@ +#define CHECK_TIMENAMESPACE +#include "tst-spawn4.c" diff --git a/posix/tst-spawn4.c b/posix/tst-spawn4.c index 9eac2d1080..29b7a6215d 100644 --- a/posix/tst-spawn4.c +++ b/posix/tst-spawn4.c @@ -21,13 +21,21 @@ #include #include -#include #include +#include #include +#include +#include static int do_test (void) { +#ifdef CHECK_TIMENAMESPACE + support_become_root(); + if (!support_enter_time_namespace ()) + return EXIT_UNSUPPORTED; +#endif + char *scriptname; int fd = create_temp_file ("tst-spawn4.", &scriptname); TEST_VERIFY_EXIT (fd >= 0); diff --git a/posix/tst-spawn5-timens.c b/posix/tst-spawn5-timens.c new file mode 100644 index 0000000000..8d46819222 --- /dev/null +++ b/posix/tst-spawn5-timens.c @@ -0,0 +1,2 @@ +#define CHECK_TIMENAMESPACE +#include "tst-spawn5.c" diff --git a/posix/tst-spawn5.c b/posix/tst-spawn5.c index dd5b3f9357..045ab15358 100644 --- a/posix/tst-spawn5.c +++ b/posix/tst-spawn5.c @@ -28,8 +28,10 @@ #include #include -#include +#include #include +#include +#include #include #include @@ -278,6 +280,12 @@ do_test (int argc, char *argv[]) /* Ignore the application name. */ handle_restart (argc - 1, &argv[1]); +#ifdef CHECK_TIMENAMESPACE + support_become_root(); + if (!support_enter_time_namespace ()) + return EXIT_UNSUPPORTED; +#endif + TEST_VERIFY_EXIT (argc == 2 || argc == 5); int i; diff --git a/posix/tst-spawn6-timens.c b/posix/tst-spawn6-timens.c new file mode 100644 index 0000000000..a23d068ce5 --- /dev/null +++ b/posix/tst-spawn6-timens.c @@ -0,0 +1,2 @@ +#define CHECK_TIMENAMESPACE +#include "tst-spawn6.c" diff --git a/posix/tst-spawn6.c b/posix/tst-spawn6.c index 044abd8535..4c55a1c110 100644 --- a/posix/tst-spawn6.c +++ b/posix/tst-spawn6.c @@ -25,12 +25,14 @@ #include #include #include +#include #include #include +#include +#include #include -#include #include -#include +#include #include #ifndef PATH_MAX @@ -124,6 +126,12 @@ run_subprogram (int argc, char *argv[], const posix_spawnattr_t *attr, static int run_test (int argc, char *argv[]) { +#ifdef CHECK_TIMENAMESPACE + support_become_root(); + if (!support_enter_time_namespace ()) + return EXIT_UNSUPPORTED; +#endif + /* We must have either: - four parameters left if called initially: + path to ld.so optional diff --git a/sysdeps/unix/sysv/linux/closefrom_fallback.c b/sysdeps/unix/sysv/linux/closefrom_fallback.c index a9dd0c46b2..cb0642c637 100644 --- a/sysdeps/unix/sysv/linux/closefrom_fallback.c +++ b/sysdeps/unix/sysv/linux/closefrom_fallback.c @@ -28,7 +28,7 @@ /proc/self/fd open will trigger a fallback that tries to close a file descriptor before proceed. */ _Bool -__closefrom_fallback (int from, _Bool dirfd_fallback) +__closefrom_fallback (unsigned int from, unsigned int to, _Bool dirfd_fallback) { int dirfd = __open_nocancel (FD_TO_FILENAME_PREFIX, O_RDONLY | O_DIRECTORY, 0); @@ -40,7 +40,7 @@ __closefrom_fallback (int from, _Bool dirfd_fallback) return false; /* The closefrom should work even when process can't open new files. */ - for (int i = from; i < INT_MAX; i++) + for (int i = from; i <= to; i++) { int r = __close_nocancel (i); if (r == 0 || (r == -1 && errno != EBADF)) @@ -84,6 +84,8 @@ __closefrom_fallback (int from, _Bool dirfd_fallback) if (fd == dirfd || fd < from) continue; + if (fd > to) + break; /* We ignore close errors because EBADF, EINTR, and EIO means the descriptor has been released. */ diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c index d6f5ca89cd..4ba7c2fc4f 100644 --- a/sysdeps/unix/sysv/linux/spawni.c +++ b/sysdeps/unix/sysv/linux/spawni.c @@ -44,7 +44,11 @@ third issue is done by a stack allocation in parent, and by using a field in struct spawn_args where the child can write an error code. CLONE_VFORK ensures that the parent does not run until the - child has either exec'ed successfully or exited. */ + child has either exec'ed successfully or exited. + + If the clone with CLONE_VM and CLONE_VFORK fails (due any kernel limitation + such as time namespace), only CLONE_VFORK is used instead and the + preparation and execve failures are communicated with a pipe. */ /* The Unix standard contains a long explanation of the way to signal @@ -67,6 +71,7 @@ struct posix_spawn_args char *const *envp; int xflags; int err; + int pipe[2]; }; /* Older version requires that shell script without shebang definition @@ -94,15 +99,59 @@ maybe_script_execute (struct posix_spawn_args *args) } } +/* If the file operation would clobber the pipe fd used to communicate with + parent, dup the pipe onto an unoccupied file descriptor. */ +static inline bool +spawni_fa_handle_pipe (const struct __spawn_action *fa, int p[]) +{ + int fd; + + switch (fa->tag) + { + case spawn_do_close: + fd = fa->action.close_action.fd; + break; + case spawn_do_open: + fd = fa->action.open_action.fd; + break; + case spawn_do_dup2: + fd = fa->action.dup2_action.newfd; + break; + case spawn_do_fchdir: + fd = fa->action.fchdir_action.fd; + default: + return true; + } + + if (fd == p[1]) + { + int r = __fcntl (p[1], F_DUPFD_CLOEXEC); + if (r < 0) + return false; + __close_nocancel (p[1]); + p[1] = r; + } + + return true; +} + +static inline bool +spawni_fa_closerange (int from, int to) +{ + int r = INLINE_SYSCALL_CALL (close_range, from, to, 0); + return r == 0 || __closefrom_fallback (from, to, false); +} + /* 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). */ -static int -__spawni_child (void *arguments) +static _Noreturn int +spawni_child (void *arguments) { struct posix_spawn_args *args = arguments; const posix_spawnattr_t *restrict attr = args->attr; const posix_spawn_file_actions_t *file_actions = args->fa; + bool use_pipe = args->pipe[0] != -1; /* The child must ensure that no signal handler are enabled because it shared memory with parent, so the signal disposition must be either SIG_DFL or @@ -113,6 +162,9 @@ __spawni_child (void *arguments) struct sigaction sa; memset (&sa, '\0', sizeof (sa)); + if (use_pipe) + __close (args->pipe[0]); + sigset_t hset; __sigprocmask (SIG_BLOCK, 0, &hset); for (int sig = 1; sig < _NSIG; ++sig) @@ -181,6 +233,9 @@ __spawni_child (void *arguments) { struct __spawn_action *action = &file_actions->__actions[cnt]; + if (use_pipe && !spawni_fa_handle_pipe (action, args->pipe)) + goto fail; + switch (action->tag) { case spawn_do_close: @@ -233,6 +288,11 @@ __spawni_child (void *arguments) break; case spawn_do_dup2: + if (use_pipe && action->action.dup2_action.fd == args->pipe[1]) + { + errno = EBADF; + goto fail; + } /* Austin Group issue #411 requires adddup2 action with source and destination being equal to remove close-on-exec flag. */ if (action->action.dup2_action.fd @@ -264,8 +324,20 @@ __spawni_child (void *arguments) case spawn_do_closefrom: { int lowfd = action->action.closefrom_action.from; - int r = INLINE_SYSCALL_CALL (close_range, lowfd, ~0U, 0); - if (r != 0 && !__closefrom_fallback (lowfd, false)) + /* Skip the pipe descriptor if it is used. No need to handle + it since it is created with O_CLOEXEC. */ + if (use_pipe && args->pipe[1] == lowfd) + { + if (!spawni_fa_closerange (lowfd + 1u, ~0U)) + goto fail; + } + else if (use_pipe && args->pipe[1] > lowfd) + { + if (!spawni_fa_closerange (lowfd, args->pipe[1] - 1) + || !spawni_fa_closerange (args->pipe[1] + 1u, ~0U)) + goto fail; + } + else if (!spawni_fa_closerange (lowfd, ~0U)) goto fail; } break; @@ -300,10 +372,112 @@ fail: (EINTERNALBUG) describing that, use ECHILD. Another option would be to set args->err to some negative sentinel and have the parent abort(), but that seems needlessly harsh. */ - args->err = errno ? : ECHILD; + int ret = errno ? : ECHILD; + if (use_pipe) + { + while (__write_nocancel (args->pipe[1], &ret, sizeof (ret)) < 0) + if (errno == EPIPE || errno == EBADF) + break; + } + else + args->err = ret; + _exit (SPAWN_ERROR); } +static pid_t +clone_call (struct posix_spawn_args *args, int flags, void *stack, + size_t stack_size) +{ + struct clone_args clone_args = + { + .flags = flags, + .exit_signal = SIGCHLD, + .stack = (uintptr_t) stack, + .stack_size = stack_size, + }; + return __clone_internal (&clone_args, spawni_child, args); +} + +/* Spawn a new process using clone with CLONE_VM | CLONE_VFORK (to optimize + memory and overcommit) and return TRUE if the helper was created or if the + failure was not due resource exhaustion. */ +static bool +spawni_clone (struct posix_spawn_args *args, pid_t *new_pid, int *ec, + void *stack, size_t stack_size) +{ + /* The clone flags used will create a new child that will run in the same + memory space (CLONE_VM) and the execution of calling thread will be + suspend until the child calls execve or _exit. + + Also since the calling thread execution will be suspend, there is not + need for CLONE_SETTLS. Although parent and child share the same TLS + namespace, there will be no concurrent access for TLS variables (errno + for instance). */ + *new_pid = clone_call (args, CLONE_VM | CLONE_VFORK, stack, stack_size); + + /* It needs to collect the case where the auxiliary process was created + but failed to execute the file (due either any preparation step or + for execve itself). */ + if (*new_pid > 0) + { + /* Also, it handles the unlikely case where the auxiliary process was + terminated before calling execve as if it was successfully. The + args.err is set to 0 as default and changed to a positive value + only in case of failure, so in case of premature termination + due a signal args.err will remain zeroed and it will be up to + caller to actually collect it. */ + *ec = args->err; + if (*ec > 0) + /* There still an unlikely case where the child is cancelled after + setting args.err, due to a positive error value. Also there is + possible pid reuse race (where the kernel allocated the same pid + to an unrelated process). Unfortunately due synchronization + issues where the kernel might not have the process collected + the waitpid below can not use WNOHANG. */ + __waitpid (*new_pid, NULL, 0); + } + else + *ec = errno; + + /* There is no much point in retrying with fork and exec if kernel returns a + failure due resource exhaustion. */ + return *new_pid > 0 || (errno == ENOMEM || errno == EAGAIN); +} + +/* Fallback spawn case which does not use CLONE_VM. Any preparation step or + execve failure is passed with a pipe, which requires additional care by + the helper stating process since it additional file descriptors handle. */ +static void +spawni_fork (struct posix_spawn_args *args, pid_t *new_pid, int *ec, + char *stack, size_t stack_size) +{ + if (__pipe2 (args->pipe, O_CLOEXEC) != 0) + { + *ec = errno; + return; + } + + /* Do not trigger atfork handler nor any internal state reset since the + helper process will call execve. */ + *new_pid = clone_call (args, CLONE_VFORK, stack, stack_size); + + __close (args->pipe[1]); + + if (*new_pid > 0) + { + if (__read (args->pipe[0], ec, sizeof *ec) != sizeof *ec) + /* A successful execve will close the helper process pipe end. */ + *ec = 0; + else + __waitpid (*new_pid, NULL, 0); + } + else + *ec = errno; + + __close (args->pipe[0]); +} + /* Spawn a new process executing PATH with the attributes describes in *ATTRP. Before running the process perform the actions described in FILE-ACTIONS. */ static int @@ -367,49 +541,16 @@ __spawnix (pid_t * pid, const char *file, args.argc = argc; args.envp = envp; args.xflags = xflags; + args.pipe[0] = args.pipe[1] = -1; __libc_signal_block_all (&args.oldmask); - /* The clone flags used will create a new child that will run in the same - memory space (CLONE_VM) and the execution of calling thread will be - suspend until the child calls execve or _exit. - - Also since the calling thread execution will be suspend, there is not - need for CLONE_SETTLS. Although parent and child share the same TLS - namespace, there will be no concurrent access for TLS variables (errno - for instance). */ - struct clone_args clone_args = - { - .flags = CLONE_VM | CLONE_VFORK, - .exit_signal = SIGCHLD, - .stack = (uintptr_t) stack, - .stack_size = stack_size, - }; - new_pid = __clone_internal (&clone_args, __spawni_child, &args); - - /* It needs to collect the case where the auxiliary process was created - but failed to execute the file (due either any preparation step or - for execve itself). */ - if (new_pid > 0) - { - /* Also, it handles the unlikely case where the auxiliary process was - terminated before calling execve as if it was successfully. The - args.err is set to 0 as default and changed to a positive value - only in case of failure, so in case of premature termination - due a signal args.err will remain zeroed and it will be up to - caller to actually collect it. */ - ec = args.err; - if (ec > 0) - /* There still an unlikely case where the child is cancelled after - setting args.err, due to a positive error value. Also there is - possible pid reuse race (where the kernel allocated the same pid - to an unrelated process). Unfortunately due synchronization - issues where the kernel might not have the process collected - the waitpid below can not use WNOHANG. */ - __waitpid (new_pid, NULL, 0); - } - else - ec = errno; + /* clone with CLONE_VM | CLONE_VFORK may fail for some namespace restriction + (for instance Linux does not allow processes in different time namespaces + to share address space) and in this case clone fails with EINVAL. Retry + with fork and exec. */ + if (!spawni_clone (&args, &new_pid, &ec, stack, stack_size)) + spawni_fork (&args, &new_pid, &ec, stack, stack_size); __munmap (stack, stack_size);