From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS22989 209.51.188.0/24 X-Spam-Status: No, score=-3.7 required=3.0 tests=AWL,BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 1BB5C1F462 for ; Mon, 10 Jun 2019 15:29:35 +0000 (UTC) Received: from localhost ([::1]:47704 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1haMEk-0007rQ-Eq for normalperson@yhbt.net; Mon, 10 Jun 2019 11:29:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48758) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1haMEb-0007iW-13 for bug-gnulib@gnu.org; Mon, 10 Jun 2019 11:29:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1haMEU-0007ze-TZ for bug-gnulib@gnu.org; Mon, 10 Jun 2019 11:29:20 -0400 Received: from mo6-p00-ob.smtp.rzone.de ([2a01:238:20a:202:5300::6]:27897) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1haMER-0007tx-Vh for bug-gnulib@gnu.org; Mon, 10 Jun 2019 11:29:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1560180548; s=strato-dkim-0002; d=clisp.org; h=Message-ID:Date:Subject:To:From:X-RZG-CLASS-ID:X-RZG-AUTH:From: Subject:Sender; bh=7gT94BEp80ho4fZiMyBFIabMhEtQtPVaUhuFCkth4wQ=; b=d8LC8uBgGjitmXNjaLEvA75TWxdvbmTPaWSZWOAa5ZO6cPImqc2HFxsDwBC8O2cHuX YZtTzT2bYAF7ZehQAYcIQYdS+W+TfrdnBxWUijWVhISzk9VJoSTNo9Lt3qyj7BtfRY5F ak5FmpcIsLYy4vWFuamfdIKjrT/wcxrZaDIYLXj5e3DbcWWDFnGycBWXWEaWy0lLLm3H xxbSDKGRgSLy/WY09vu/9YOlbGNPROOEquepouJoZTSdVgV9La+zSuXXXfX2j88gKfdv 0pbil9omo2RYV3BXhn3fAcYpKDZnlOUsvJ+U7ySjAO5rOkbGsVJ3Lokp+sqaFucryMD0 m/vw== X-RZG-AUTH: ":Ln4Re0+Ic/6oZXR1YgKryK8brlshOcZlIWs+iCP5vnk6shH+AHjwLuWOGaf0y5RW" X-RZG-CLASS-ID: mo00 Received: from bruno.haible.de by smtp.strato.de (RZmta 44.22 DYNA|AUTH) with ESMTPSA id z04bc9v5AFT4iU4 (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Mon, 10 Jun 2019 17:29:04 +0200 (CEST) From: Bruno Haible To: bug-gnulib@gnu.org Subject: posix_spawn fixes Date: Mon, 10 Jun 2019 17:29:04 +0200 Message-ID: <8918495.I2bNyhKAuR@omega> User-Agent: KMail/5.1.3 (Linux/4.4.0-145-generic; KDE/5.18.0; x86_64; ; ) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart4325007.UoN0XLIYEV" Content-Transfer-Encoding: 7Bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a01:238:20a:202:5300::6 X-BeenThere: bug-gnulib@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Gnulib discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnulib-bounces+normalperson=yhbt.net@gnu.org Sender: "bug-gnulib" This is a multi-part message in MIME format. --nextPart4325007.UoN0XLIYEV Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" 2019-06-10 Bruno Haible doc: Document existence of posix_spawn_file_actions_addchdir module. * doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi: Mention the posix_spawn_file_actions_addchdir module. 2019-06-10 Bruno Haible posix_spawn_file_actions_addfchdir: New module. * lib/spawn.in.h (posix_spawn_file_actions_addfchdir): New declaration. * lib/spawn_int.h (struct __spawn_action): Add tag 'spawn_do_fchdir' and union member 'fchdir_action'. * lib/spawn_faction_addfchdir.c: New file. * lib/spawni.c (__spawni): Implement the spawn_do_fchdir action. * m4/posix_spawn_faction_addfchdir.m4: New file. * m4/posix_spawn.m4 (gl_POSIX_SPAWN_BODY): Test whether module 'posix_spawn_file_actions_addfchdir' is present and whether posix_spawn_file_actions_addfchdir_np exists. Set REPLACE_POSIX_SPAWN. * m4/spawn_h.m4 (gl_SPAWN_H): Test whether posix_spawn_file_actions_addfchdir is declared. (gl_SPAWN_H_DEFAULTS): Initialize GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR. * modules/spawn (Makefile.am): Substitute GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR. * modules/posix_spawn_file_actions_addfchdir: New file. * tests/test-spawn-c++.cc (posix_spawn_file_actions_addfchdir): Check signature. * doc/posix-functions/posix_spawn.texi: Mention the new module. * doc/posix-functions/posix_spawnp.texi: Likewise. * doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi: Likewise. 2019-06-10 Bruno Haible posix_spawn_file_actions_addfchdir: Add tests. * tests/test-posix_spawn_file_actions_addfchdir.c: New file. * tests/test-posix_spawn5.c: New file. * modules/posix_spawn_file_actions_addfchdir-tests: New file. 2019-06-10 Bruno Haible posix_spawn_file_actions_addopen: Fix possible use-after-free bug. Reported at . * lib/spawn_int.h (struct __spawn_action): Remove 'const' from path. * lib/spawn_faction_addopen.c (posix_spawn_file_actions_addopen): Make a copy of the path argument. * lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free it. 2019-06-10 Bruno Haible posix_spawn_file_actions_addchdir: Fix possible use-after-free bug. * lib/spawn_int.h (struct __spawn_action): Remove 'const' from path. * lib/spawn_faction_addchdir.c (posix_spawn_file_actions_addchdir): Make a copy of the path argument. * lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free it. --nextPart4325007.UoN0XLIYEV Content-Disposition: attachment; filename="0001-doc-Document-existence-of-posix_spawn_file_actions_a.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="0001-doc-Document-existence-of-posix_spawn_file_actions_a.patch" >From 2ad7a33b829d0378fb6765e778e4170a3fec9697 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 10 Jun 2019 16:26:03 +0200 Subject: [PATCH 1/5] doc: Document existence of posix_spawn_file_actions_addchdir module. * doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi: Mention the posix_spawn_file_actions_addchdir module. --- ChangeLog | 6 ++++++ doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi | 3 +++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index d1b8854..ac79aac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2019-06-10 Bruno Haible + doc: Document existence of posix_spawn_file_actions_addchdir module. + * doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi: Mention + the posix_spawn_file_actions_addchdir module. + +2019-06-10 Bruno Haible + posix_spawn-internal: Fix module description. * modules/posix_spawn (configure.ac): Move request to compile spawni.c from here... diff --git a/doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi b/doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi index a40a3d7..1c4c0a4 100644 --- a/doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi +++ b/doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi @@ -14,3 +14,6 @@ Portability problems not fixed by Gnulib: This function is missing on many non-glibc platforms: glibc 2.28, Mac OS X 10.5, FreeBSD 12.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.0, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize + +Note: Gnulib has a module @code{posix_spawn_file_actions_addchdir} that +provides equivalent functionality, just without the suffix @code{_np}. -- 2.7.4 --nextPart4325007.UoN0XLIYEV Content-Disposition: attachment; filename="0002-posix_spawn_file_actions_addfchdir-New-module.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="0002-posix_spawn_file_actions_addfchdir-New-module.patch" >From d822de87e4d1c97e422e48332542dfe7261c7d82 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 10 Jun 2019 16:16:16 +0200 Subject: [PATCH 2/5] posix_spawn_file_actions_addfchdir: New module. * lib/spawn.in.h (posix_spawn_file_actions_addfchdir): New declaration. * lib/spawn_int.h (struct __spawn_action): Add tag 'spawn_do_fchdir' and union member 'fchdir_action'. * lib/spawn_faction_addfchdir.c: New file. * lib/spawni.c (__spawni): Implement the spawn_do_fchdir action. * m4/posix_spawn_faction_addfchdir.m4: New file. * m4/posix_spawn.m4 (gl_POSIX_SPAWN_BODY): Test whether module 'posix_spawn_file_actions_addfchdir' is present and whether posix_spawn_file_actions_addfchdir_np exists. Set REPLACE_POSIX_SPAWN. * m4/spawn_h.m4 (gl_SPAWN_H): Test whether posix_spawn_file_actions_addfchdir is declared. (gl_SPAWN_H_DEFAULTS): Initialize GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR. * modules/spawn (Makefile.am): Substitute GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR. * modules/posix_spawn_file_actions_addfchdir: New file. * tests/test-spawn-c++.cc (posix_spawn_file_actions_addfchdir): Check signature. * doc/posix-functions/posix_spawn.texi: Mention the new module. * doc/posix-functions/posix_spawnp.texi: Likewise. * doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi: Likewise. --- ChangeLog | 30 ++++++++++ .../posix_spawn_file_actions_addfchdir_np.texi | 3 + doc/posix-functions/posix_spawn.texi | 7 ++- doc/posix-functions/posix_spawnp.texi | 7 ++- lib/spawn.in.h | 35 +++++++++++ lib/spawn_faction_addfchdir.c | 68 ++++++++++++++++++++++ lib/spawn_int.h | 7 ++- lib/spawni.c | 6 ++ m4/posix_spawn.m4 | 11 +++- m4/posix_spawn_faction_addfchdir.m4 | 20 +++++++ m4/spawn_h.m4 | 54 +++++++++-------- modules/posix_spawn_file_actions_addfchdir | 30 ++++++++++ modules/spawn | 3 + tests/test-spawn-c++.cc | 5 ++ 14 files changed, 254 insertions(+), 32 deletions(-) create mode 100644 lib/spawn_faction_addfchdir.c create mode 100644 m4/posix_spawn_faction_addfchdir.m4 create mode 100644 modules/posix_spawn_file_actions_addfchdir diff --git a/ChangeLog b/ChangeLog index ac79aac..ecf1d47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,35 @@ 2019-06-10 Bruno Haible + posix_spawn_file_actions_addfchdir: New module. + * lib/spawn.in.h (posix_spawn_file_actions_addfchdir): New declaration. + * lib/spawn_int.h (struct __spawn_action): Add tag 'spawn_do_fchdir' and + union member 'fchdir_action'. + * lib/spawn_faction_addfchdir.c: New file. + * lib/spawni.c (__spawni): Implement the spawn_do_fchdir action. + * m4/posix_spawn_faction_addfchdir.m4: New file. + * m4/posix_spawn.m4 (gl_POSIX_SPAWN_BODY): Test whether module + 'posix_spawn_file_actions_addfchdir' is present and whether + posix_spawn_file_actions_addfchdir_np exists. Set REPLACE_POSIX_SPAWN. + * m4/spawn_h.m4 (gl_SPAWN_H): Test whether + posix_spawn_file_actions_addfchdir is declared. + (gl_SPAWN_H_DEFAULTS): Initialize + GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, + HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, + REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR. + * modules/spawn (Makefile.am): Substitute + GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, + HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR, + REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR. + * modules/posix_spawn_file_actions_addfchdir: New file. + * tests/test-spawn-c++.cc (posix_spawn_file_actions_addfchdir): Check + signature. + * doc/posix-functions/posix_spawn.texi: Mention the new module. + * doc/posix-functions/posix_spawnp.texi: Likewise. + * doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi: + Likewise. + +2019-06-10 Bruno Haible + doc: Document existence of posix_spawn_file_actions_addchdir module. * doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi: Mention the posix_spawn_file_actions_addchdir module. diff --git a/doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi b/doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi index bb82195..6da90fd 100644 --- a/doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi +++ b/doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi @@ -14,3 +14,6 @@ Portability problems not fixed by Gnulib: This function is missing on all non-glibc platforms: glibc 2.28, Mac OS X 10.5, FreeBSD 12.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.4, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize + +Note: Gnulib has a module @code{posix_spawn_file_actions_addfchdir} that +provides equivalent functionality, just without the suffix @code{_np}. diff --git a/doc/posix-functions/posix_spawn.texi b/doc/posix-functions/posix_spawn.texi index bed0e79..6513608 100644 --- a/doc/posix-functions/posix_spawn.texi +++ b/doc/posix-functions/posix_spawn.texi @@ -24,6 +24,7 @@ This function does not work on some platforms: AIX 6.1 (under particular circumstances), mingw. @end itemize -The Gnulib module @code{posix_spawn_file_actions_addchdir} provides an -additional action, that consists in changing the current directory of -the child process before starting the specified program. +The Gnulib modules @code{posix_spawn_file_actions_addchdir} and +@code{posix_spawn_file_actions_addfchdir} provide additional actions, +that consist in changing the current directory of the child process +before starting the specified program. diff --git a/doc/posix-functions/posix_spawnp.texi b/doc/posix-functions/posix_spawnp.texi index 6cfec28..3dd8ed4 100644 --- a/doc/posix-functions/posix_spawnp.texi +++ b/doc/posix-functions/posix_spawnp.texi @@ -24,6 +24,7 @@ This function does not work on some platforms: AIX 6.1 (under particular circumstances), mingw. @end itemize -The Gnulib module @code{posix_spawn_file_actions_addchdir} provides an -additional action, that consists in changing the current directory of -the child process before starting the specified program. +The Gnulib modules @code{posix_spawn_file_actions_addchdir} and +@code{posix_spawn_file_actions_addfchdir} provide additional actions, +that consist in changing the current directory of the child process +before starting the specified program. diff --git a/lib/spawn.in.h b/lib/spawn.in.h index df95e4a..721d70f 100644 --- a/lib/spawn.in.h +++ b/lib/spawn.in.h @@ -913,6 +913,41 @@ _GL_WARN_ON_USE (posix_spawn_file_actions_addchdir, # endif #endif +#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +/* Add an action to FILE-ACTIONS which tells the implementation to call + 'fchdir' to the given directory during the 'spawn' call. */ +# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawn_file_actions_addfchdir rpl_posix_spawn_file_actions_addfchdir +# endif +_GL_FUNCDECL_RPL (posix_spawn_file_actions_addfchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd) + __THROW _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_spawn_file_actions_addfchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd)); +# else +# if !@HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +_GL_FUNCDECL_SYS (posix_spawn_file_actions_addfchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd) + __THROW _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (posix_spawn_file_actions_addfchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd)); +# endif +_GL_CXXALIASWARN (posix_spawn_file_actions_addfchdir); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawn_file_actions_addfchdir +# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR +_GL_WARN_ON_USE (posix_spawn_file_actions_addfchdir, + "posix_spawn_file_actions_addfchdir is unportable - " + "use gnulib module posix_spawn_file_actions_addfchdir for portability"); +# endif +#endif + #endif /* _@GUARD_PREFIX@_SPAWN_H */ #endif /* _@GUARD_PREFIX@_SPAWN_H */ diff --git a/lib/spawn_faction_addfchdir.c b/lib/spawn_faction_addfchdir.c new file mode 100644 index 0000000..504856d --- /dev/null +++ b/lib/spawn_faction_addfchdir.c @@ -0,0 +1,68 @@ +/* Copyright (C) 2018-2019 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#include + +#if !_LIBC +# define __sysconf(open_max) getdtablesize () +#endif + +#if REPLACE_POSIX_SPAWN +# include "spawn_int.h" +#endif + +/* Add an action to FILE-ACTIONS which tells the implementation to call + 'fchdir' to the given directory during the 'spawn' call. */ +int +posix_spawn_file_actions_addfchdir (posix_spawn_file_actions_t *file_actions, + int fd) +#undef posix_spawn_file_actions_addfchdir +{ + int maxfd = __sysconf (_SC_OPEN_MAX); + + /* Test for the validity of the file descriptor. */ + if (fd < 0 || fd >= maxfd) + return EBADF; + +#if !REPLACE_POSIX_SPAWN + return posix_spawn_file_actions_addfchdir_np (file_actions, fd); +#else + /* 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; + + { + struct __spawn_action *rec; + + /* Add the new value. */ + rec = &file_actions->_actions[file_actions->_used]; + rec->tag = spawn_do_fchdir; + rec->action.fchdir_action.fd = fd; + + /* Account for the new entry. */ + ++file_actions->_used; + + return 0; + } +#endif +} diff --git a/lib/spawn_int.h b/lib/spawn_int.h index 06b8004..584c1bb 100644 --- a/lib/spawn_int.h +++ b/lib/spawn_int.h @@ -24,7 +24,8 @@ struct __spawn_action spawn_do_close, spawn_do_dup2, spawn_do_open, - spawn_do_chdir + spawn_do_chdir, + spawn_do_fchdir } tag; union @@ -49,6 +50,10 @@ struct __spawn_action { const char *path; } chdir_action; + struct + { + int fd; + } fchdir_action; } action; }; diff --git a/lib/spawni.c b/lib/spawni.c index 39e99a0..087f45c 100644 --- a/lib/spawni.c +++ b/lib/spawni.c @@ -290,6 +290,12 @@ __spawni (pid_t *pid, const char *file, /* The 'chdir' call failed. */ _exit (SPAWN_ERROR); break; + + case spawn_do_fchdir: + if (fchdir (action->action.fchdir_action.fd) < 0) + /* The 'fchdir' call failed. */ + _exit (SPAWN_ERROR); + break; } } } diff --git a/m4/posix_spawn.m4 b/m4/posix_spawn.m4 index d50dcc9..0128390 100644 --- a/m4/posix_spawn.m4 +++ b/m4/posix_spawn.m4 @@ -1,4 +1,4 @@ -# posix_spawn.m4 serial 16 +# posix_spawn.m4 serial 17 dnl Copyright (C) 2008-2019 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -42,6 +42,15 @@ AC_DEFUN([gl_POSIX_SPAWN_BODY], REPLACE_POSIX_SPAWN=1 fi ]) + m4_ifdef([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR], + [dnl Module 'posix_spawn_file_actions_addfchdir' is present. + AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addfchdir_np]) + if test $ac_cv_func_posix_spawn_file_actions_addfchdir_np = no; then + dnl In order to implement the posix_spawn_file_actions_addfchdir + dnl function, we need to replace the entire posix_spawn facility. + REPLACE_POSIX_SPAWN=1 + fi + ]) if test $REPLACE_POSIX_SPAWN = 0; then gl_POSIX_SPAWN_WORKS case "$gl_cv_func_posix_spawn_works" in diff --git a/m4/posix_spawn_faction_addfchdir.m4 b/m4/posix_spawn_faction_addfchdir.m4 new file mode 100644 index 0000000..ef2f9d6 --- /dev/null +++ b/m4/posix_spawn_faction_addfchdir.m4 @@ -0,0 +1,20 @@ +# posix_spawn_faction_addfchdir.m4 serial 1 +dnl Copyright (C) 2018-2019 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR], +[ + AC_REQUIRE([gl_SPAWN_H_DEFAULTS]) + AC_REQUIRE([AC_PROG_CC]) + gl_POSIX_SPAWN + AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addfchdir posix_spawn_file_actions_addfchdir_np]) + if test $ac_cv_func_posix_spawn_file_actions_addfchdir = yes; then + dnl This function is not yet standardized. Therefore override the + dnl system's implementation always. + REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=1 + else + HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=0 + fi +]) diff --git a/m4/spawn_h.m4 b/m4/spawn_h.m4 index 561caa7..95cb25d 100644 --- a/m4/spawn_h.m4 +++ b/m4/spawn_h.m4 @@ -1,4 +1,4 @@ -# spawn_h.m4 serial 17 +# spawn_h.m4 serial 18 dnl Copyright (C) 2008-2019 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -53,7 +53,8 @@ AC_DEFUN([gl_SPAWN_H], posix_spawnattr_getschedparam posix_spawnattr_setschedparam posix_spawn_file_actions_init posix_spawn_file_actions_destroy posix_spawn_file_actions_addopen posix_spawn_file_actions_addclose - posix_spawn_file_actions_adddup2 posix_spawn_file_actions_addchdir]) + posix_spawn_file_actions_adddup2 posix_spawn_file_actions_addchdir + posix_spawn_file_actions_addfchdir]) ]) dnl Checks whether the system has the functions posix_spawn. @@ -89,28 +90,29 @@ AC_DEFUN([gl_SPAWN_MODULE_INDICATOR], AC_DEFUN([gl_SPAWN_H_DEFAULTS], [ - GNULIB_POSIX_SPAWN=0; AC_SUBST([GNULIB_POSIX_SPAWN]) - GNULIB_POSIX_SPAWNP=0; AC_SUBST([GNULIB_POSIX_SPAWNP]) - GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT]) - GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR]) - GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE]) - GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2]) - GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN]) - GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY]) - GNULIB_POSIX_SPAWNATTR_INIT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_INIT]) - GNULIB_POSIX_SPAWNATTR_GETFLAGS=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETFLAGS]) - GNULIB_POSIX_SPAWNATTR_SETFLAGS=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETFLAGS]) - GNULIB_POSIX_SPAWNATTR_GETPGROUP=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETPGROUP]) - GNULIB_POSIX_SPAWNATTR_SETPGROUP=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETPGROUP]) - GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM]) - GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM]) - GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY]) - GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY]) - GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT]) - GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT]) - GNULIB_POSIX_SPAWNATTR_GETSIGMASK=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSIGMASK]) - GNULIB_POSIX_SPAWNATTR_SETSIGMASK=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSIGMASK]) - GNULIB_POSIX_SPAWNATTR_DESTROY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_DESTROY]) + GNULIB_POSIX_SPAWN=0; AC_SUBST([GNULIB_POSIX_SPAWN]) + GNULIB_POSIX_SPAWNP=0; AC_SUBST([GNULIB_POSIX_SPAWNP]) + GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT]) + GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR]) + GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE]) + GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2]) + GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR]) + GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN]) + GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY]) + GNULIB_POSIX_SPAWNATTR_INIT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_INIT]) + GNULIB_POSIX_SPAWNATTR_GETFLAGS=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETFLAGS]) + GNULIB_POSIX_SPAWNATTR_SETFLAGS=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETFLAGS]) + GNULIB_POSIX_SPAWNATTR_GETPGROUP=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETPGROUP]) + GNULIB_POSIX_SPAWNATTR_SETPGROUP=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETPGROUP]) + GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM]) + GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM]) + GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY]) + GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY]) + GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT]) + GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT]) + GNULIB_POSIX_SPAWNATTR_GETSIGMASK=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSIGMASK]) + GNULIB_POSIX_SPAWNATTR_SETSIGMASK=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSIGMASK]) + GNULIB_POSIX_SPAWNATTR_DESTROY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_DESTROY]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_POSIX_SPAWN=1; AC_SUBST([HAVE_POSIX_SPAWN]) HAVE_POSIX_SPAWNATTR_T=1; AC_SUBST([HAVE_POSIX_SPAWNATTR_T]) @@ -118,6 +120,8 @@ AC_DEFUN([gl_SPAWN_H_DEFAULTS], AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_T]) HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR=1; AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR]) + HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=1; + AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR]) REPLACE_POSIX_SPAWN=0; AC_SUBST([REPLACE_POSIX_SPAWN]) REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR=0; AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR]) @@ -125,6 +129,8 @@ AC_DEFUN([gl_SPAWN_H_DEFAULTS], AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE]) REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=0; AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2]) + REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=0; + AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR]) REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN=0; AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN]) ]) diff --git a/modules/posix_spawn_file_actions_addfchdir b/modules/posix_spawn_file_actions_addfchdir new file mode 100644 index 0000000..cd9cb99 --- /dev/null +++ b/modules/posix_spawn_file_actions_addfchdir @@ -0,0 +1,30 @@ +Description: +posix_spawn_file_actions_addfchdir() function: augment a child process actions +specification. + +Files: +lib/spawn_faction_addfchdir.c +lib/spawn_int.h +m4/posix_spawn_faction_addfchdir.m4 + +Depends-on: +spawn +posix_spawn_file_actions_init [test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN = 1 || test $HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = 0 || test $REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = 1] + +configure.ac: +gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR +if test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN = 1 || test $HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = 0 || test $REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = 1; then + AC_LIBOBJ([spawn_faction_addfchdir]) +fi +gl_SPAWN_MODULE_INDICATOR([posix_spawn_file_actions_addfchdir]) + +Makefile.am: + +Include: + + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/spawn b/modules/spawn index dc861d3..6e03294 100644 --- a/modules/spawn +++ b/modules/spawn @@ -35,6 +35,7 @@ spawn.h: spawn.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)/g' \ -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE)/g' \ -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)/g' \ -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN)/g' \ -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY)/g' \ -e 's/@''GNULIB_POSIX_SPAWNATTR_INIT''@/$(GNULIB_POSIX_SPAWNATTR_INIT)/g' \ @@ -55,10 +56,12 @@ spawn.h: spawn.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's|@''HAVE_POSIX_SPAWNATTR_T''@|$(HAVE_POSIX_SPAWNATTR_T)|g' \ -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_T''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_T)|g' \ -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)|g' \ + -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)|g' \ -e 's|@''REPLACE_POSIX_SPAWN''@|$(REPLACE_POSIX_SPAWN)|g' \ -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)|g' \ -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE)|g' \ -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)|g' \ -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ diff --git a/tests/test-spawn-c++.cc b/tests/test-spawn-c++.cc index 2ba1cc4..119917f 100644 --- a/tests/test-spawn-c++.cc +++ b/tests/test-spawn-c++.cc @@ -137,6 +137,11 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawn_file_actions_addchdir, int, (posix_spawn_file_actions_t *, const char *)); #endif +#if GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR +SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawn_file_actions_addfchdir, int, + (posix_spawn_file_actions_t *, int)); +#endif + int main () -- 2.7.4 --nextPart4325007.UoN0XLIYEV Content-Disposition: attachment; filename="0003-posix_spawn_file_actions_addfchdir-Add-tests.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="0003-posix_spawn_file_actions_addfchdir-Add-tests.patch" >From fbb40ec10e333cff0b9845572065edd9e66eac79 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 10 Jun 2019 16:17:35 +0200 Subject: [PATCH 3/5] posix_spawn_file_actions_addfchdir: Add tests. * tests/test-posix_spawn_file_actions_addfchdir.c: New file. * tests/test-posix_spawn5.c: New file. * modules/posix_spawn_file_actions_addfchdir-tests: New file. --- ChangeLog | 7 ++ modules/posix_spawn_file_actions_addfchdir-tests | 20 +++ tests/test-posix_spawn5.c | 148 +++++++++++++++++++++++ tests/test-posix_spawn_file_actions_addfchdir.c | 44 +++++++ 4 files changed, 219 insertions(+) create mode 100644 modules/posix_spawn_file_actions_addfchdir-tests create mode 100644 tests/test-posix_spawn5.c create mode 100644 tests/test-posix_spawn_file_actions_addfchdir.c diff --git a/ChangeLog b/ChangeLog index ecf1d47..7bbf5fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2019-06-10 Bruno Haible + posix_spawn_file_actions_addfchdir: Add tests. + * tests/test-posix_spawn_file_actions_addfchdir.c: New file. + * tests/test-posix_spawn5.c: New file. + * modules/posix_spawn_file_actions_addfchdir-tests: New file. + +2019-06-10 Bruno Haible + posix_spawn_file_actions_addfchdir: New module. * lib/spawn.in.h (posix_spawn_file_actions_addfchdir): New declaration. * lib/spawn_int.h (struct __spawn_action): Add tag 'spawn_do_fchdir' and diff --git a/modules/posix_spawn_file_actions_addfchdir-tests b/modules/posix_spawn_file_actions_addfchdir-tests new file mode 100644 index 0000000..5e50695 --- /dev/null +++ b/modules/posix_spawn_file_actions_addfchdir-tests @@ -0,0 +1,20 @@ +Files: +tests/test-posix_spawn_file_actions_addfchdir.c +tests/test-posix_spawn5.c +tests/signature.h +tests/macros.h + +Depends-on: +posix_spawn_file_actions_init +posix_spawnp-tests + +configure.ac: + +Makefile.am: +TESTS += test-posix_spawn_file_actions_addfchdir +check_PROGRAMS += test-posix_spawn_file_actions_addfchdir + +if POSIX_SPAWN_PORTED +TESTS += test-posix_spawn5 +check_PROGRAMS += test-posix_spawn5 +endif diff --git a/tests/test-posix_spawn5.c b/tests/test-posix_spawn5.c new file mode 100644 index 0000000..805f666 --- /dev/null +++ b/tests/test-posix_spawn5.c @@ -0,0 +1,148 @@ +/* Test of posix_spawn() function with 'fchdir' action. + Copyright (C) 2008-2019 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2018. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int +fd_safer (int fd) +{ + if (0 <= fd && fd <= 2) + { + int f = fd_safer (dup (fd)); + int e = errno; + close (fd); + errno = e; + fd = f; + } + + return fd; +} + +int +main () +{ + char *argv[2] = { (char *) "pwd", NULL }; + int rootfd; + int ifd[2]; + sigset_t blocked_signals; + sigset_t fatal_signal_set; + posix_spawn_file_actions_t actions; + bool actions_allocated; + posix_spawnattr_t attrs; + bool attrs_allocated; + int err; + pid_t child; + int fd; + FILE *fp; + char line[80]; + int status; + int exitstatus; + + rootfd = open ("/", O_RDONLY); + if (rootfd < 0) + { + perror ("cannot open directory"); + exit (1); + } + if (pipe (ifd) < 0 || (ifd[0] = fd_safer (ifd[0])) < 0) + { + perror ("cannot create pipe"); + exit (1); + } + sigprocmask (SIG_SETMASK, NULL, &blocked_signals); + sigemptyset (&fatal_signal_set); + sigaddset (&fatal_signal_set, SIGINT); + sigaddset (&fatal_signal_set, SIGTERM); + sigaddset (&fatal_signal_set, SIGHUP); + sigaddset (&fatal_signal_set, SIGPIPE); + sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL); + actions_allocated = false; + attrs_allocated = false; + if ((err = posix_spawn_file_actions_init (&actions)) != 0 + || (actions_allocated = true, + (err = posix_spawn_file_actions_adddup2 (&actions, ifd[1], STDOUT_FILENO)) != 0 + || (err = posix_spawn_file_actions_addclose (&actions, ifd[1])) != 0 + || (err = posix_spawn_file_actions_addclose (&actions, ifd[0])) != 0 + || (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO, "/dev/null", O_RDONLY, 0)) != 0 + || (err = posix_spawn_file_actions_addfchdir (&actions, rootfd)) != 0 + || (err = posix_spawnattr_init (&attrs)) != 0 + || (attrs_allocated = true, + (err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0 + || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0) + || (err = posix_spawnp (&child, "pwd", &actions, &attrs, argv, environ)) != 0)) + { + if (actions_allocated) + posix_spawn_file_actions_destroy (&actions); + if (attrs_allocated) + posix_spawnattr_destroy (&attrs); + sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL); + errno = err; + perror ("subprocess failed"); + exit (1); + } + posix_spawn_file_actions_destroy (&actions); + posix_spawnattr_destroy (&attrs); + sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL); + close (ifd[1]); + fd = ifd[0]; + fp = fdopen (fd, "r"); + if (fp == NULL) + { + fprintf (stderr, "fdopen() failed\n"); + exit (1); + } + if (fread (line, 1, 80, fp) < 2) + { + fprintf (stderr, "could not read expected output\n"); + exit (1); + } + if (memcmp (line, "/\n", 2) != 0) + { + fprintf (stderr, "read output is not the expected output"); + exit (1); + } + fclose (fp); + status = 0; + while (waitpid (child, &status, 0) != child) + ; + if (!WIFEXITED (status)) + { + fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status); + exit (1); + } + exitstatus = WEXITSTATUS (status); + if (exitstatus != 0) + { + fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus); + exit (1); + } + return 0; +} diff --git a/tests/test-posix_spawn_file_actions_addfchdir.c b/tests/test-posix_spawn_file_actions_addfchdir.c new file mode 100644 index 0000000..d7df690 --- /dev/null +++ b/tests/test-posix_spawn_file_actions_addfchdir.c @@ -0,0 +1,44 @@ +/* Test posix_spawn_file_actions_addfchdir() function. + Copyright (C) 2018-2019 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +#include + +#include "signature.h" +SIGNATURE_CHECK (posix_spawn_file_actions_addfchdir, int, + (posix_spawn_file_actions_t *, int)); + +#include +#include +#include +#include + +#include "macros.h" + +int +main (void) +{ + posix_spawn_file_actions_t actions; + + ASSERT (posix_spawn_file_actions_init (&actions) == 0); + + ASSERT (posix_spawn_file_actions_addfchdir (&actions, 3) == 0); + + posix_spawn_file_actions_destroy (&actions); + + return 0; +} -- 2.7.4 --nextPart4325007.UoN0XLIYEV Content-Disposition: attachment; filename="0004-posix_spawn_file_actions_addopen-Fix-possible-use-af.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="0004-posix_spawn_file_actions_addopen-Fix-possible-use-af.patch" >From 765146c33361b46aa2c592e980b16069094c6000 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 10 Jun 2019 16:50:04 +0200 Subject: [PATCH 4/5] posix_spawn_file_actions_addopen: Fix possible use-after-free bug. Reported at . * lib/spawn_int.h (struct __spawn_action): Remove 'const' from path. * lib/spawn_faction_addopen.c (posix_spawn_file_actions_addopen): Make a copy of the path argument. * lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free it. --- ChangeLog | 10 ++++++++++ lib/spawn_faction_addopen.c | 47 +++++++++++++++++++++++++++++---------------- lib/spawn_faction_destroy.c | 29 +++++++++++++++++++++++++++- lib/spawn_int.h | 2 +- 4 files changed, 69 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7bbf5fa..16f720d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2019-06-10 Bruno Haible + posix_spawn_file_actions_addopen: Fix possible use-after-free bug. + Reported at . + * lib/spawn_int.h (struct __spawn_action): Remove 'const' from path. + * lib/spawn_faction_addopen.c (posix_spawn_file_actions_addopen): Make + a copy of the path argument. + * lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free + it. + +2019-06-10 Bruno Haible + posix_spawn_file_actions_addfchdir: Add tests. * tests/test-posix_spawn_file_actions_addfchdir.c: New file. * tests/test-posix_spawn5.c: New file. diff --git a/lib/spawn_faction_addopen.c b/lib/spawn_faction_addopen.c index 6b4422f..ab4f727 100644 --- a/lib/spawn_faction_addopen.c +++ b/lib/spawn_faction_addopen.c @@ -20,6 +20,8 @@ #include #include +#include +#include #include #if !_LIBC @@ -47,27 +49,38 @@ posix_spawn_file_actions_addopen (posix_spawn_file_actions_t *file_actions, #if !REPLACE_POSIX_SPAWN return posix_spawn_file_actions_addopen (file_actions, fd, path, oflag, mode); #else - /* 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; - { - struct __spawn_action *rec; + /* Copy PATH, because the caller may free it before calling posix_spawn() + or posix_spawnp(). */ + char *path_copy = strdup (path); + if (path_copy == NULL) + return ENOMEM; + + /* 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. */ + free (path_copy); + return ENOMEM; + } + + { + struct __spawn_action *rec; - /* Add the new value. */ - rec = &file_actions->_actions[file_actions->_used]; - rec->tag = spawn_do_open; - rec->action.open_action.fd = fd; - rec->action.open_action.path = path; - rec->action.open_action.oflag = oflag; - rec->action.open_action.mode = mode; + /* Add the new value. */ + rec = &file_actions->_actions[file_actions->_used]; + rec->tag = spawn_do_open; + rec->action.open_action.fd = fd; + rec->action.open_action.path = path_copy; + rec->action.open_action.oflag = oflag; + rec->action.open_action.mode = mode; - /* Account for the new entry. */ - ++file_actions->_used; + /* Account for the new entry. */ + ++file_actions->_used; - return 0; + return 0; + } } #endif } diff --git a/lib/spawn_faction_destroy.c b/lib/spawn_faction_destroy.c index 6d9ec80..0640da4 100644 --- a/lib/spawn_faction_destroy.c +++ b/lib/spawn_faction_destroy.c @@ -21,11 +21,38 @@ #include +#if REPLACE_POSIX_SPAWN +# include "spawn_int.h" +#endif + /* Initialize data structure for file attribute for 'spawn' call. */ int posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions) +#undef posix_spawn_file_actions_destroy { - /* Free the memory allocated. */ +#if !REPLACE_POSIX_SPAWN + return posix_spawn_file_actions_destroy (file_actions); +#else + int i; + + /* Free the paths in the open actions. */ + for (i = 0; i < file_actions->_used; ++i) + { + struct __spawn_action *sa = &file_actions->_actions[i]; + switch (sa->tag) + { + case spawn_do_open: + free (sa->action.open_action.path); + break; + default: + /* No cleanup required. */ + break; + } + } + + /* Free the array of actions. */ free (file_actions->_actions); + return 0; +#endif } diff --git a/lib/spawn_int.h b/lib/spawn_int.h index 584c1bb..08c477a 100644 --- a/lib/spawn_int.h +++ b/lib/spawn_int.h @@ -42,7 +42,7 @@ struct __spawn_action struct { int fd; - const char *path; + char *path; int oflag; mode_t mode; } open_action; -- 2.7.4 --nextPart4325007.UoN0XLIYEV Content-Disposition: attachment; filename="0005-posix_spawn_file_actions_addchdir-Fix-possible-use-a.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="0005-posix_spawn_file_actions_addchdir-Fix-possible-use-a.patch" >From b827d8a6fab0c25eaf0c59b94c5bbef00efeeae5 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 10 Jun 2019 16:51:51 +0200 Subject: [PATCH 5/5] posix_spawn_file_actions_addchdir: Fix possible use-after-free bug. * lib/spawn_int.h (struct __spawn_action): Remove 'const' from path. * lib/spawn_faction_addchdir.c (posix_spawn_file_actions_addchdir): Make a copy of the path argument. * lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free it. --- ChangeLog | 9 +++++++++ lib/spawn_faction_addchdir.c | 41 +++++++++++++++++++++++++++-------------- lib/spawn_faction_destroy.c | 1 + lib/spawn_int.h | 2 +- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 16f720d..217779e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2019-06-10 Bruno Haible + posix_spawn_file_actions_addchdir: Fix possible use-after-free bug. + * lib/spawn_int.h (struct __spawn_action): Remove 'const' from path. + * lib/spawn_faction_addchdir.c (posix_spawn_file_actions_addchdir): Make + a copy of the path argument. + * lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free + it. + +2019-06-10 Bruno Haible + posix_spawn_file_actions_addopen: Fix possible use-after-free bug. Reported at . * lib/spawn_int.h (struct __spawn_action): Remove 'const' from path. diff --git a/lib/spawn_faction_addchdir.c b/lib/spawn_faction_addchdir.c index b270e1f..925874c 100644 --- a/lib/spawn_faction_addchdir.c +++ b/lib/spawn_faction_addchdir.c @@ -19,6 +19,8 @@ #include #include +#include +#include #if REPLACE_POSIX_SPAWN # include "spawn_int.h" @@ -34,24 +36,35 @@ posix_spawn_file_actions_addchdir (posix_spawn_file_actions_t *file_actions, #if !REPLACE_POSIX_SPAWN return posix_spawn_file_actions_addchdir_np (file_actions, path); #else - /* 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; - { - struct __spawn_action *rec; + /* Copy PATH, because the caller may free it before calling posix_spawn() + or posix_spawnp(). */ + char *path_copy = strdup (path); + if (path_copy == NULL) + return ENOMEM; + + /* 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. */ + free (path_copy); + return ENOMEM; + } + + { + struct __spawn_action *rec; - /* Add the new value. */ - rec = &file_actions->_actions[file_actions->_used]; - rec->tag = spawn_do_chdir; - rec->action.chdir_action.path = path; + /* Add the new value. */ + rec = &file_actions->_actions[file_actions->_used]; + rec->tag = spawn_do_chdir; + rec->action.chdir_action.path = path_copy; - /* Account for the new entry. */ - ++file_actions->_used; + /* Account for the new entry. */ + ++file_actions->_used; - return 0; + return 0; + } } #endif } diff --git a/lib/spawn_faction_destroy.c b/lib/spawn_faction_destroy.c index 0640da4..d7156a0 100644 --- a/lib/spawn_faction_destroy.c +++ b/lib/spawn_faction_destroy.c @@ -42,6 +42,7 @@ posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions) switch (sa->tag) { case spawn_do_open: + case spawn_do_chdir: free (sa->action.open_action.path); break; default: diff --git a/lib/spawn_int.h b/lib/spawn_int.h index 08c477a..bcf8bbf 100644 --- a/lib/spawn_int.h +++ b/lib/spawn_int.h @@ -48,7 +48,7 @@ struct __spawn_action } open_action; struct { - const char *path; + char *path; } chdir_action; struct { -- 2.7.4 --nextPart4325007.UoN0XLIYEV--