[exim-dev] [Bug 1071] Privilege dropping due to -C or -D opt…

Top Page
Delete this message
Reply to this message
Author: Phil Pennock
Date:  
To: exim-dev
Old-Topics: [exim-dev] [Bug 1071] New: Privilege due to -C or -D options dropping breaks logging
Subject: [exim-dev] [Bug 1071] Privilege dropping due to -C or -D options breaks logging
------- You are receiving this mail because: -------
You are on the CC list for the bug.

http://bugs.exim.org/show_bug.cgi?id=1071

Phil Pennock <pdp@???> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED





--- Comment #5 from Phil Pennock <pdp@???> 2011-01-23 09:46:19 ---
Okay, I'll start with a walk-through of what happens, from debug traces of
deliveries both with only-whitelisted macros and with a blacklisted macro, and
refer to the Spec, which also documents where root is retained.

In this, we'll assume that the Exim run-time user is "eximrun".

Exim starts as root. Binds privileged sockets, etc, drops privileges to
eximrun, sits and waits for connection.

Exim accepts a connection, forks; in the child process, handles inbound mail,
no exec, still user eximrun. Processes ACLs, then fork/exec's Exim for the
routing and delivery.

Exim refuses to raise privileges from eximrun to root because of
non-whitelisted macro, so drops back to eximrun. Logs this at panic. But does
not exit.

Exim then performs Routing. Normally routing happens as root, to be able to
read .forward files and to later switch identities to a non-eximrun user for
delivery, if specified in the Transport. See section 52.2 of Spec. See option
"deliver_drop_privilege" to drop privs sooner, if you don't need to use "user =
.." in a Transport and don't need to read .forward files with permissions that
deny access to eximrun.

So with code designed to be runnable either as root or as eximrun, it ends up
running as eximrun because of the non-whitelisted macro.

Later, Exim forks a delivery process. This drops privileges to eximrun for the
remote SMTP delivery. When the delivery process is done, the parent routing
process does the logging of delivery. It then drops privileges to eximrun for
some tidy-up, before exiting.

In my -d(ebug) tests, everything is logged fine, nothing goes wrong.
Without -d(ebug), I confirm that I can reproduce the bug-report. How
inconvenient.

Exim's child process handling opens fd 2 onto fd 1, so that stderr is
available, so log_stderr is set, so exim.c:3347 sets really_exim to FALSE.
Then the new code around exim.c:3541 only re-enables normal logging if
deliver_drop_privilege is true. Because it's not true, it proceeds to log at
panic level. In log_write(), because really_exim is false, the problems are
written to stderr, not to the logs, before returning.

Our options (not mutually exclusive):
 (1) dropping privileges could be LOG_PANIC_DIE, abort early, let the admin
know what has happened
 (2) if untrusted macros are provided on the command-line, -bd could refuse to
go into daemon mode because this inherently involves re-invoking exim
      (a) if untrusted macros, -bd could LOG_PANIC_DIE *unless*
deliver_drop_privilege is set, but that feels too band-aidy to me
 (3) Around 3347, we record if we are unsetting a previously TRUE really_exim
("coerced_really_exim_off") and then around 3541, we turn on really_exim if
coerced_really_exim_off.


I think I'll look at just option 3 for this release, but we should consider the
other options too.


--
Configure bugmail: http://bugs.exim.org/userprefs.cgi?tab=email