| From: | Haibo Yan <tristan(dot)yim(at)gmail(dot)com> |
|---|---|
| To: | "Jonathan Gonzalez V(dot)" <jonathan(at)abdiel(dot)eu> |
| Cc: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | Re: Introduce psystem() to replace system() |
| Date: | 2026-08-11 01:11:33 |
| Message-ID: | CABXr29GzFpfJjZip1ApuPLGQVF_PXY2Za0qo6SvM+Ppf658q2A@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Mon, Aug 10, 2026 at 12:28 PM Jonathan Gonzalez V. <jonathan(at)abdiel(dot)eu>
wrote:
>
> Hello!!
>
> For some time I've been wondering why PostgreSQL needs system() calls,
> which use a shell that can lead to many problems, and also why it
> requires a shell to run a command.
>
> I first started thinking about this when I was trying to run a full
> distroless PostgreSQL container. It turns out that isn't possible since
> the shell is a requirement, and distroless containers are secure exactly
> _because_ there's no shell to execute any command other than the ones
> that are meant to be executed.
>
> After some research I found out that using system() has other problems,
> like issues related to quoting that are really painful to solve [0][1],
> and also the exit codes control[2]. Both topics have already been
> discussed on the list.
>
> But the main argument now for me is security. Not having a shell avoids
> any possible PATH injection, missing quoting to escape a command, or new
> lines that the shell interprets differently from what you'd expect.
>
> After some thinking I came up with a small interface, which only purpose
> is to replace system() calls in a more smooth way using execv() under
> the hood. I suppose you could use execl() but I've decided to keep it
> simple, leaving the opportunity to expand in the future. I already
> implemented one call with `pg_ctl initdb` as an example.
>
> There's an important topic related to using shell versus not a shell. In
> some places like `archive_command` people may use `&&`, but this idea
> aims to avoid this kind of behavior since it's not secure. Probably we
> can implement a way to run commands in sequence, or simply tell the
> users that this isn't allowed anymore, but it's possible to trigger
> commands in sequence since the interface allows to manipulate the STDIN
> and STDOUT.
>
> I would like to open the discussion here if this is the right direction.
> There's a lot to do and this still a work in progress, the current patch
> is small and simple, but already provides building blocks in this
> direction.
>
> Hi Jonathan
Thanks for working on this. I think avoiding the shell for cases where
PostgreSQL is just
invoking a known executable makes sense.
There is some related work here which may be worth looking at:
That effort ran into some similar issues around replacing system()/popen()
and handling the
fork/exec boundary.
A few things I noticed in this patch:
1. system() and execv() do not have the same semantics. For internal
commands such as pg_ctl
invoking initdb, that is probably fine and preferable. But for things like
archive_command,
shell features such as PATH lookup, &&, pipes and redirection are part of
the existing
interface, so changing those would be a compatibility decision rather than
just an
implementation change.
2. For pipelines, pcommand_exec() only knows the stdin/stdout/stderr FDs.
After fork(),
however, a child may inherit other pipe endpoints as well. Those need to be
closed before
exec(), otherwise an unused write end can keep a pipe alive and prevent EOF
from being seen.
3. I also wonder about returning errno from pcommand_exec(). An execv()
failure should
probably remain distinguishable from a program that successfully execs and
later exits with
the same numeric status. An error pipe from child to parent may be useful
here.
Overall I like the direction, but I think it would be useful to reuse some
of the lessons
from the earlier pg_system() / pg_popen() work before this grows into a
more general process
/pipeline API.
Regards,
Haibo
> [0] https://www.postgresql.org/message-id/7606.1153326421%40sss.pgh.pa.us
> [1]
> https://www.postgresql.org/message-id/CA%2BTgmobBmWWCgPUd04NGoQ%3D_XvcidV%2BsE2F7KChEXfs8KBPg6w%40mail.gmail.com
> [2] https://www.postgresql.org/message-id/21292.1358698487%40sss.pgh.pa.us
>
> --
> Jonathan Gonzalez V.
> EDB https://enterprisedb.com
>
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Bharath Rupireddy | 2026-08-11 01:25:00 | Re: Introduce XID age based replication slot invalidation |
| Previous Message | Tom Lane | 2026-08-11 00:56:22 | Re: plpython tests fail against python 3.14 under Valgrind |