Thorsten Kukuk via Postfix-users:
> On Wed, Sep 16, 2026 at 5:16?PM Wietse Venema via Postfix-users
> <[email protected]> wrote:
> >
> > Thorsten Kukuk via Postfix-users:
> > > Hi,
> > >
> > > Several Linux distributions work on enabling NoNewPrivs
> > > (https://docs.kernel.org/userspace-api/no_new_privs.html) system wide
> > > during boot, which disables the setuid and setgid bits.
> > >
> > > For most applications in a standard base system, solutions to replace
> > > setuid/setgid binaries already exist, or people are working on them.
> > > One problem is postfix, which includes three setgid binaries.
> > >
> > > I have some questions and ideas about this:
> > >
> > > 1. postlog: What was the reason for hiding its socket in a restricted
> > > directory and allowing access only via a setgid binary? Why wasn't the
> > > socket moved into a readable/writable directory?
> > > Ok, I think this is the most un-important binary. Logging on Linux is
> > > mostly done via journald today, and some big Linux distributions don't
> > > even set the bit.
> >
> > The postlog client enforces a policy (who can call postlog).  It
> > also limits the number of concurrent requests by the number of
> > postlog processes that an attacker may run (one request per process).
> 
> None of this exists in the current code. It does not check any
> policies (that code is disabled with "#if 0") and there are no limit
> checks.
> 
> This DoS attack is possible today with postlog, too.

postlog limits the number of concurrent requests by the number of
postlog processes that an attacker may run (one request per process).

The limit is the number of processes that a hostile user can run.

> > With a world-writable socket, it would be trivial to DOS the postlogd.
> 
> > > 2. postdrop
> > > The postdrop binary needs to be setgid maildrop to store emails in the
> > > queue under /var/spool/postfix. It's only called by the sendmail
> > > wrapper and communicates via stdin/stdout over a pipe. It's simple to
> > > extend this to be called by a systemd socket, there is a minimal
> > > invasive PoC: 
> > > https://github.com/thkukuk/postfix/commit/f4ecc0f02e82ac8c1e6d1823bafde05c699a29f8
> >
> > postdrop enforces sanity checks on the queue file record stream;
> > enforces the message size limit; enforces policies on who can submit
> > mail and what envelope sender they can specify; it informs the
> > pickup daemon of new mail; and it limits the number of concurrent
> > requests by the number of postdrop processes that an attacker may
> > run (one request per process).
> >
> > With a world-writable maildrop directory and pickup socket it would
> > be trivial for any user to send mail as anyone, to DOS the Postfix
> > queue, and to DOS the pickup daemon.
> 
> Please read what I wrote. I don't want to make the maildrop directory
> world-writable. My idea would be, what today more and more services
> are already doing on Linux, start the application via a socket and not
> via exec. The behavior is the same with this approach.

It is not limited by the number of processes that a hostile user can run.

> > > 3. postqueue
> > > The postqueue command is only called directly by users, by mailq, or
> > > by the sendmail wrapper. Or did I miss something?
> > > The setgid is needed to access the sockets for the postfix daemons.
> > > This is only required, since the ACL check for users is done in
> > > postqueue and not in the daemons itself.  Was there ever a discussion
> > > to move that ACL check into the daemon (e.g. on Linux via SO_PEERCRED,
> > > I think BSD has something similar).  That would avoid the problem,
> > > that an admin didn't setup the permissions correct or somebody finds
> > > an exploitable bug in the setgid binary.
> >
> > postqueue enforces policies for who can view the mail queue or who
> > can flush the mail queue. It limits what information may be sent
> > to a Postfix daemon, and limits the number of concurrent requests
> > by the number of postqueue processes that an attacker may run (one
> > request per process).
> >
> > With a world-writable socket, it would be trivial to DOS the showq
> > and flush daemons.
> 
> And the question remains: why must this be handled on the client side
> and not on the server side?

The DOS is limited by the number of limit of postqueue processes
that a hostile user can run.


That said, if there is a way to limit DOS the number of concurrent
requests that a hostile user can make, then the following may work.

- postlog, postdrop, and postqueue implement both systemd client
  and server code. Each program contains a systemd client half and
  a systemd server half.

- If a program is run systemd client mode, it connects to the
  corresponding systemd service which runs the same program. It may
  also pass the service connection over stdout.

- If the program is run in systemd server mode, then it does the
  traditional postdrop stuff.

- The client half and server half exchange some information such
  as user credentials. Maybe the postdrop client can forward the
  systemd socket to stdout (i.e. sendmail).

This way, the shape of Postfix does not change. All the systemd
stuff is hidden inside postlog, postdrop, and postqueue, 
implemented of course by reusable library functions.

How will this prevent sendmail from hanging during boot, before
systemd has started the postlog, postdrop, and postqueue jobs?

        Wietse
_______________________________________________
Postfix-users mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to