Re: [PATCH] Add posix_spawn_file_actions_addclosefrom_np
Chris Hanson <[email protected]> Sun, 10 May 2026 14:26:47 -0700
| Newsgroups | gmane.os.netbsd.devel.kernel |
|---|---|
| Message-ID | <[email protected]> |
Here’s my final updated patch that also ensures the posix_spawn_file_actions_addclosefrom_np symbol is appropriately weak, guarded by _NETBSD_SOURCE, the libc version is updated, etc. It should apply cleanly to trunk and (modulo the libc versioning) should also pull back to NetBSD 11 trivially if it’s desired there. (I’d certainly like it to go into 11 if possible, but 11 is producing release candidates, so...) Any -- Chris
0001-Add-posix_spawn_file_actions_addclosefrom_np.patch
(application/octet-stream, 14.2 KB)
From 56f82a540724523352f2f940069e26a514cec125 Mon Sep 17 00:00:00 2001 From: Chris Hanson <[email protected]> Date: Sat, 18 Apr 2026 16:30:18 -0700 Subject: [PATCH] Add posix_spawn_file_actions_addclosefrom_np Add support for a closefrom(3) action to posix_spawn_file_actions_t. This can be used to ensure all but specific low-numbered descriptors are closed in the child process. Rationale: In a large or complex application or one using many libraries, the caller of posix_spawn(3) can't necessarily have complete knowledge of the state of all descriptors that could potentially be inherited by the child process. --- distrib/sets/lists/base/shl.mi | 4 +- distrib/sets/lists/debug/shl.mi | 4 +- doc/CHANGES | 2 + include/spawn.h | 4 ++ lib/libc/gen/posix_spawn.3 | 1 + .../gen/posix_spawn_file_actions_addopen.3 | 39 +++++++++++++++++-- lib/libc/gen/posix_spawn_file_actions_init.3 | 1 + lib/libc/gen/posix_spawn_fileactions.c | 26 +++++++++++++ lib/libc/include/namespace.h | 4 ++ lib/libc/shlib_version | 2 +- sys/kern/kern_exec.c | 10 ++++- sys/sys/spawn.h | 10 ++++- .../lib/libc/gen/posix_spawn/h_fileactions.c | 11 ++++++ .../lib/libc/gen/posix_spawn/t_fileactions.c | 25 +++++++++++- 14 files changed, 131 insertions(+), 12 deletions(-) diff --git distrib/sets/lists/base/shl.mi distrib/sets/lists/base/shl.mi index dc61b3a5efa9..1655e5c40147 100644 --- distrib/sets/lists/base/shl.mi +++ distrib/sets/lists/base/shl.mi @@ -22,7 +22,7 @@ ./lib/libblocklist.so.0.1 base-sys-shlib dynamicroot ./lib/libc.so base-sys-shlib dynamicroot ./lib/libc.so.12 base-sys-shlib dynamicroot -./lib/libc.so.12.224 base-sys-shlib dynamicroot +./lib/libc.so.12.225 base-sys-shlib dynamicroot ./lib/libcrypt.so base-sys-shlib dynamicroot ./lib/libcrypt.so.1 base-sys-shlib dynamicroot ./lib/libcrypt.so.1.0 base-sys-shlib dynamicroot @@ -267,7 +267,7 @@ ./usr/lib/libc++.so.1.0 base-sys-shlib compatfile,libcxx ./usr/lib/libc.so base-sys-shlib compatfile ./usr/lib/libc.so.12 base-sys-shlib compatfile -./usr/lib/libc.so.12.224 base-sys-shlib compatfile +./usr/lib/libc.so.12.225 base-sys-shlib compatfile ./usr/lib/libcbor.so base-sys-shlib compatfile ./usr/lib/libcbor.so.0 base-sys-shlib compatfile ./usr/lib/libcbor.so.0.5 base-sys-shlib compatfile diff --git distrib/sets/lists/debug/shl.mi distrib/sets/lists/debug/shl.mi index f29c98ef9319..b27607ae7876 100644 --- distrib/sets/lists/debug/shl.mi +++ distrib/sets/lists/debug/shl.mi @@ -3,7 +3,7 @@ ./usr/libdata/debug/lib base-sys-usr debug,dynamicroot,compatdir ./usr/libdata/debug/lib/libavl.so.0.0.debug comp-zfs-debug debug,dynamicroot,zfs ./usr/libdata/debug/lib/libblocklist.so.0.1.debug comp-sys-debug debug,dynamicroot -./usr/libdata/debug/lib/libc.so.12.224.debug comp-sys-debug debug,dynamicroot +./usr/libdata/debug/lib/libc.so.12.225.debug comp-sys-debug debug,dynamicroot ./usr/libdata/debug/lib/libcrypt.so.1.0.debug comp-sys-debug debug,dynamicroot ./usr/libdata/debug/lib/libcrypto.so.12.0.debug comp-sys-debug debug,dynamicroot,openssl=10 ./usr/libdata/debug/lib/libcrypto.so.14.1.debug comp-sys-debug debug,dynamicroot,openssl=11 @@ -89,7 +89,7 @@ ./usr/libdata/debug/usr/lib/libbsdmalloc.so.0.1.debug comp-sys-debug debug,compatfile ./usr/libdata/debug/usr/lib/libbz2.so.1.1.debug comp-sys-debug debug,compatfile ./usr/libdata/debug/usr/lib/libc++.so.1.0.debug comp-sys-debug debug,compatfile,libcxx -./usr/libdata/debug/usr/lib/libc.so.12.224.debug comp-sys-debug debug,compatfile +./usr/libdata/debug/usr/lib/libc.so.12.225.debug comp-sys-debug debug,compatfile ./usr/libdata/debug/usr/lib/libcbor.so.0.5.debug comp-sys-debug debug,compatfile ./usr/libdata/debug/usr/lib/libcom_err.so.8.0.debug comp-krb5-debug debug,compatfile,kerberos ./usr/libdata/debug/usr/lib/libcrypt.so.1.0.debug comp-sys-debug debug,compatfile diff --git doc/CHANGES doc/CHANGES index 5678c01952ad..d93db8886d5d 100644 --- doc/CHANGES +++ doc/CHANGES @@ -238,6 +238,8 @@ Changes from NetBSD 11.0 to NetBSD 12.0: tzdata: Updated to 2026b (using 2026bgtz) [kre 20260429] pthread(3): add pthread_main_np(3) [wiz 20260501] zstd(1): import 1.5.7 [christos 20260501] + posix_spawn(3): Add posix_spawn_file_actions_addclosefrom_np + function from FreeBSD. [cmh 20260418] libarchive: Import libarchive-3.8.7. [christos 20260503] acpi(4): Updated ACPICA to 20260408. [christos 20260503] byacc: Update to 20260126. [christos 20260503] diff --git include/spawn.h include/spawn.h index 32cdd85ca27f..d5963cdb1942 100644 --- include/spawn.h +++ include/spawn.h @@ -60,6 +60,10 @@ int posix_spawn_file_actions_addchdir(posix_spawn_file_actions_t * __restrict, const char * __restrict); int posix_spawn_file_actions_addfchdir(posix_spawn_file_actions_t *, int); +#if defined(_NETBSD_SOURCE) +int posix_spawn_file_actions_addclosefrom_np(posix_spawn_file_actions_t *, int); +#endif + /* * Spawn attributes */ diff --git lib/libc/gen/posix_spawn.3 lib/libc/gen/posix_spawn.3 index 6ca4a59a0810..379da1708fd6 100644 --- lib/libc/gen/posix_spawn.3 +++ lib/libc/gen/posix_spawn.3 @@ -444,6 +444,7 @@ is returned. .Xr vfork 2 , .Xr posix_spawn_file_actions_addchdir 3 , .Xr posix_spawn_file_actions_addclose 3 , +.Xr posix_spawn_file_actions_addclosefrom_np 3 , .Xr posix_spawn_file_actions_adddup2 3 , .Xr posix_spawn_file_actions_addfchdir 3 , .Xr posix_spawn_file_actions_addopen 3 , diff --git lib/libc/gen/posix_spawn_file_actions_addopen.3 lib/libc/gen/posix_spawn_file_actions_addopen.3 index 9a23d6f9e899..1f9fc26a8790 100644 --- lib/libc/gen/posix_spawn_file_actions_addopen.3 +++ lib/libc/gen/posix_spawn_file_actions_addopen.3 @@ -36,14 +36,15 @@ .\" .\" $FreeBSD: src/lib/libc/gen/posix_spawn_file_actions_addopen.3,v 1.2.2.1.4.1 2010/06/14 02:09:06 kensmith Exp $ .\" -.Dd February 2, 2014 +.Dd April 18, 2026 .Dt POSIX_SPAWN_FILE_ACTIONS_ADDOPEN 3 .Os .Sh NAME .Nm posix_spawn_file_actions_addopen , .Nm posix_spawn_file_actions_adddup2 , -.Nm posix_spawn_file_actions_addclose -.Nd "add open, dup2 or close action to spawn file actions object" +.Nm posix_spawn_file_actions_addclose , +.Nm posix_spawn_file_actions_addclosefrom_np +.Nd "add open, dup2, close, or closefrom action to spawn file actions object" .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -54,8 +55,10 @@ .Fn posix_spawn_file_actions_adddup2 "posix_spawn_file_actions_t * file_actions" "int fildes" "int newfildes" .Ft int .Fn posix_spawn_file_actions_addclose "posix_spawn_file_actions_t * file_actions" "int fildes" +.Ft int +.Fn posix_spawn_file_actions_addclosefrom_np "posix_spawn_file_actions_t * file_actions" "int fildes" .Sh DESCRIPTION -These functions add an open, dup2 or close action to a spawn +These functions add an open, dup2, close, or closefrom action to a spawn file actions object. .Pp A spawn file actions object is of type @@ -140,6 +143,21 @@ close(fildes) .Pp had been called) when a new process is spawned using this file actions object. +.Pp +The +.Fn posix_spawn_file_actions_addclosefrom_np +function adds a closefrom action to the object +referenced by +.Fa file_actions +that causes the file descriptor +.Fa filedes +and all higher file descriptors to be closed (as if +.Bd -literal -offset indent +closefrom(filedes) +.Ed +.Pp +had been called) when a new process is spawned using this file actions +object. .Sh RETURN VALUES Upon successful completion, these functions return zero; otherwise, an error number is returned to indicate the error. @@ -164,6 +182,7 @@ Insufficient memory exists to add to the spawn file actions object. .Xr close 2 , .Xr dup2 2 , .Xr open 2 , +.Xr closefrom 3 , .Xr posix_spawn 3 , .Xr posix_spawn_file_actions_destroy 3 , .Xr posix_spawn_file_actions_init 3 , @@ -176,6 +195,10 @@ and .Fn posix_spawn_file_actions_addclose functions conform to .St -p1003.1-2001 . +.Pp +The +.Fn posix_spawn_file_actions_addclosefrom_np +function is a non-standard extension. .Sh HISTORY The .Fn posix_spawn_file_actions_addopen , @@ -186,5 +209,13 @@ functions first appeared in .Fx 8.0 and imported for .Nx 6.0 . +.Pp +The implementation of +.Fn posix_spawn_file_actions_addclosefrom_np +is inspired by FreeBSD's +.Fn posix_spawn_file_actions_addclosefrom_np +and first appeared in +.Nx 12.0 . .Sh AUTHORS .An Ed Schouten Aq Mt [email protected] +.An Chris Hanson Aq Mt [email protected] diff --git lib/libc/gen/posix_spawn_file_actions_init.3 lib/libc/gen/posix_spawn_file_actions_init.3 index d33a09c267b3..366a68d45d16 100644 --- lib/libc/gen/posix_spawn_file_actions_init.3 +++ lib/libc/gen/posix_spawn_file_actions_init.3 @@ -89,6 +89,7 @@ Insufficient memory exists to initialize the spawn file actions object. .Sh SEE ALSO .Xr posix_spawn 3 , .Xr posix_spawn_file_actions_addclose 3 , +.Xr posix_spawn_file_actions_addclosefrom_np 3 , .Xr posix_spawn_file_actions_adddup2 3 , .Xr posix_spawn_file_actions_addopen 3 , .Xr posix_spawnp 3 diff --git lib/libc/gen/posix_spawn_fileactions.c lib/libc/gen/posix_spawn_fileactions.c index 1ff45c97faa5..a9335013d9e8 100644 --- lib/libc/gen/posix_spawn_fileactions.c +++ lib/libc/gen/posix_spawn_fileactions.c @@ -40,6 +40,11 @@ __RCSID("$NetBSD: posix_spawn_fileactions.c,v 1.5 2021/11/07 14:34:30 christos E #define MIN_SIZE 16 +#ifdef __weak_alias +__weak_alias(posix_spawn_file_actions_addclosefrom_np, + _posix_spawn_file_actions_addclosefrom_np) +#endif + /* * File descriptor actions */ @@ -215,3 +220,24 @@ posix_spawn_file_actions_addfchdir(posix_spawn_file_actions_t *fa, int fildes) return 0; } + +int +posix_spawn_file_actions_addclosefrom_np(posix_spawn_file_actions_t *fa, + int fildes) +{ + unsigned int i; + int error; + + if (fildes < 0) + return EBADF; + + error = posix_spawn_file_actions_getentry(fa, &i); + if (error) + return error; + + fa->fae[i].fae_action = FAE_CLOSEFROM; + fa->fae[i].fae_fildes = fildes; + fa->len++; + + return 0; +} diff --git lib/libc/include/namespace.h lib/libc/include/namespace.h index 6ac8288b9123..424a7779ea22 100644 --- lib/libc/include/namespace.h +++ lib/libc/include/namespace.h @@ -935,6 +935,10 @@ #define dladdr __dladdr #define fmtcheck __fmtcheck +/* posix_spawn */ +#define posix_spawn_file_actions_addclosefrom_np \ + _posix_spawn_file_actions_addclosefrom_np + /* RB trees */ #define rb_tree_init _rb_tree_init #define rb_tree_find_node _rb_tree_find_node diff --git lib/libc/shlib_version lib/libc/shlib_version index 7bcdd8dcbcb5..ad43eb5ef62d 100644 --- lib/libc/shlib_version +++ lib/libc/shlib_version @@ -55,4 +55,4 @@ # - remove tzsetwall(3), upstream has removed it # - move *rand48* to libcompat major=12 -minor=224 +minor=225 diff --git sys/kern/kern_exec.c sys/kern/kern_exec.c index 0d1b498ab303..0621f4d66ea8 100644 --- sys/kern/kern_exec.c +++ sys/kern/kern_exec.c @@ -2154,7 +2154,7 @@ handle_posix_spawn_file_actions(struct posix_spawn_file_actions *actions) { struct lwp *l = curlwp; register_t retval; - int error = 0, newfd; + int error = 0, newfd, fd; if (actions == NULL) return 0; @@ -2201,6 +2201,14 @@ handle_posix_spawn_file_actions(struct posix_spawn_file_actions *actions) case FAE_FCHDIR: error = do_sys_fchdir(l, fae->fae_fildes, &retval); break; + case FAE_CLOSEFROM: + /* + * as above, ignore failures from close(). + */ + for (fd = fae->fae_fildes; fd <= l->l_fd->fd_lastfile; fd++) + if (fd_getfile(fd) != NULL) + fd_close(fd); + break; } if (error) return error; diff --git sys/sys/spawn.h sys/sys/spawn.h index b04db01bd03c..ecca5c9ad541 100644 --- sys/sys/spawn.h +++ sys/sys/spawn.h @@ -47,7 +47,15 @@ struct posix_spawnattr { sigset_t sa_sigmask; }; -enum fae_action { FAE_OPEN, FAE_DUP2, FAE_CLOSE, FAE_CHDIR, FAE_FCHDIR }; +enum fae_action { + FAE_OPEN, + FAE_DUP2, + FAE_CLOSE, + FAE_CHDIR, + FAE_FCHDIR, + FAE_CLOSEFROM, +}; + typedef struct posix_spawn_file_actions_entry { enum fae_action fae_action; diff --git tests/lib/libc/gen/posix_spawn/h_fileactions.c tests/lib/libc/gen/posix_spawn/h_fileactions.c index c658600bbf1c..0d9637b7d1ec 100644 --- tests/lib/libc/gen/posix_spawn/h_fileactions.c +++ tests/lib/libc/gen/posix_spawn/h_fileactions.c @@ -100,6 +100,17 @@ main(int argc, char **argv) fprintf(stderr, "%s: stat results differ\n", getprogname()); res = EXIT_FAILURE; } + /* file descs 8 and 9 should be closed (via addclosefrom_np) */ + if (read(8, buf, BUFSIZE) != -1 || errno != EBADF) { + fprintf(stderr, "%s: filedesc 8 is not closed\n", + getprogname()); + res = EXIT_FAILURE; + } + if (read(9, buf, BUFSIZE) != -1 || errno != EBADF) { + fprintf(stderr, "%s: filedesc 9 is not closed\n", + getprogname()); + res = EXIT_FAILURE; + } return res; } diff --git tests/lib/libc/gen/posix_spawn/t_fileactions.c tests/lib/libc/gen/posix_spawn/t_fileactions.c index 57e27a0ada46..c8763ebcc42d 100644 --- tests/lib/libc/gen/posix_spawn/t_fileactions.c +++ tests/lib/libc/gen/posix_spawn/t_fileactions.c @@ -274,7 +274,7 @@ ATF_TC_HEAD(t_spawn_fileactions, tc) } ATF_TC_BODY(t_spawn_fileactions, tc) { - int fd1, fd2, fd3, status; + int fd1, fd2, fd3, fd4, fd5, fd6, fd7, status; pid_t pid; char * const args[2] = { __UNCONST("h_fileactions"), NULL }; char helper[FILENAME_MAX]; @@ -297,6 +297,29 @@ ATF_TC_BODY(t_spawn_fileactions, tc) RZ(posix_spawn_file_actions_addopen(&fa, 6, "/dev/null", O_RDWR, 0)); RZ(posix_spawn_file_actions_adddup2(&fa, 1, 7)); + /* + * Open descriptors 6 & 7 so we can get to 8 & 9 for testing + * closefrom_np, but close 6 & 7 before the spawn since the + * child process will get them via the open and dup2 actions + * above. + */ + RL(fd4 = open("/dev/null", O_RDONLY)); + ATF_REQUIRE(fd4 == 6); + + RL(fd5 = open("/dev/null", O_RDONLY)); + ATF_REQUIRE(fd5 == 7); + + RL(fd6 = open("/dev/null", O_RDONLY)); + ATF_REQUIRE(fd6 == 8); + + RL(fd7 = open("/dev/null", O_RDONLY)); + ATF_REQUIRE(fd7 == 9); + + close(fd4); + close(fd5); + + RZ(posix_spawn_file_actions_addclosefrom_np(&fa, 8)); + snprintf(helper, sizeof helper, "%s/h_fileactions", atf_tc_get_config_var(tc, "srcdir")); RZ(posix_spawn(&pid, helper, &fa, NULL, args, NULL)); -- 2.54.0