On Sat, Jan 07, 2023 at 12:12:32AM +0000, Colin Watson wrote:
> On Fri, Jan 06, 2023 at 11:55:16AM +0800, Paul Wise wrote:
> >  * posix_spawn: this uses the appropriate mechanisms on each platform,
> >    glibc might be changing this to use io_uring_spawn where possible.
> 
> I can see a few limitations here:
> 
>  * The standard API offers no way to set the working directory of the
>    child process, which would be needed for pipecmd_chdir and
>    pipecmd_fchdir.  However, glibc 2.29 added
>    posix_spawn_file_actions_addchdir_np and
>    posix_spawn_file_actions_addfchdir_np as GNU extensions.
> 
>  * I'm not totally sure how to translate pipecmd_nice into
>    posix_spawn-speak; the documentation is, uh, opaque.  It's probably
>    possible.
> 
>  * This wouldn't be usable for pipeline commands created using
>    pipecmd_new_sequence, as posix_spawn isn't guaranteed to be
>    async-signal-safe so can't be called between fork and exec, unlike
>    fork.
> 
> However, we could always just restrict the conditions under which
> posix_spawn is used, much as GLib's g_spawn_* functions do.  None of the
> above features are used on mandb's hot path, for instance.

On looking at this further, there is another more serious problem with
using posix_spawn, despite it looking initially appealing:
pipeline_install_post_fork and pipecmd_pre_exec are used heavily by
man-db, and I don't see a way to implement either using posix_spawn
today.

The uses of pipeline_install_post_fork are mainly cleanup handlers that
could perhaps mostly be avoided (though it's not clear how libpipeline
could know that).  However, we use pipecmd_pre_exec to load a seccomp
filter and in one case to drop privileges.  Privilege-dropping could
perhaps be done using the POSIX_SPAWN_RESETIDS flag instead, although
we'd likely need to add some way to request that explicitly via
libpipeline.  But I see no way to implement loading a seccomp filter for
a child process using posix_spawn.

If there were some way to load a seccomp filter without needing to run
extra code between (v)fork and exec, then that would probably allow
solving this problem.  As it stands, though, I think this means that
posix_spawn can't in practice be used by man-db, and that means that I
have little interest in implementing it in libpipeline.

(Well, I suppose it might be possible to use a helper binary to load the
seccomp filter.  But I suspect that this would erase any performance
gains from doing the fork-and-exec more efficiently.)

A shame!

-- 
Colin Watson (he/him)                              [cjwat...@debian.org]

Reply via email to