(Bug 1044, CVE-2010-4345)
---
doc/doc-docbook/spec.xfpt | 16 ++++++++++------
doc/doc-txt/ChangeLog | 4 ++++
src/src/EDITME | 7 +++----
src/src/config.h.defaults | 1 +
src/src/globals.c | 1 +
src/src/globals.h | 1 +
src/src/readconf.c | 5 ++---
7 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 1ec4181..049b2b6 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -4501,17 +4501,21 @@ existing file in the list.
.cindex "configuration file" "ownership"
.cindex "ownership" "configuration file"
The run time configuration file must be owned by root or by the user that is
-specified at compile time by the EXIM_USER option, or by the user that is
specified at compile time by the CONFIGURE_OWNER option (if set). The
-configuration file must not be world-writeable or group-writeable, unless its
-group is the one specified at compile time by the EXIM_GROUP option or by the
+configuration file must not be world-writeable, or group-writeable unless its
+group is the root group or the one specified at compile time by the
CONFIGURE_GROUP option.
&*Warning*&: In a conventional configuration, where the Exim binary is setuid
to root, anybody who is able to edit the run time configuration file has an
-easy way to run commands as root. If you make your mail administrators members
-of the Exim group, but do not trust them with root, make sure that the run time
-configuration is not group writeable.
+easy way to run commands as root. If you specify a user or group in the
+CONFIGURE_OWNER or CONFIGURE_GROUP options, then that user and/or any users
+who are members of that group will trivially be able to obtain root privileges.
+
+Up to Exim version 4.72, the run time configuration file was also permitted to
+be writeable by the Exim user and/or group. That has been changed in Exim 4.73
+since it offered a simple privilege escalation for any attacker who managed to
+compromise the Exim user account.
A default configuration file, which will work correctly in simple situations,
is provided in the file &_src/configure.default_&. If CONFIGURE_FILE
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index ccc5d79..99a6f17 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -74,6 +74,10 @@ PP/20 Added a CONTRIBUTING file. Fixed the documentation build to use http:
DW/21 Added Valgrind hooks in store.c to help it capture out-of-bounds store
access.
+DW/22 Bugzilla 1044: CVE-2010-4345 - partial fix: restrict default behaviour
+ of CONFIGURE_OWNER and CONFIGURE_GROUP options to no longer allow a
+ configuration file which is writeable by the Exim user or group.
+
Exim version 4.72
-----------------
diff --git a/src/src/EDITME b/src/src/EDITME
index 050d9ad..285e5b6 100644
--- a/src/src/EDITME
+++ b/src/src/EDITME
@@ -430,14 +430,13 @@ FIXED_NEVER_USERS=root
#------------------------------------------------------------------------------
-# By default, Exim insists that its configuration file be owned either by root
-# or by the Exim user. You can specify one additional permitted owner here.
+# By default, Exim insists that its configuration file be owned by root. You
+# can specify one additional permitted owner here.
# CONFIGURE_OWNER=
# If the configuration file is group-writeable, Exim insists by default that it
-# is owned by root or the Exim user. You can specify one additional permitted
-# group owner here.
+# is owned by root. You can specify one additional permitted group owner here.
# CONFIGURE_GROUP=
diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults
index c6895b6..9f0eba0 100644
--- a/src/src/config.h.defaults
+++ b/src/src/config.h.defaults
@@ -161,5 +161,6 @@ just in case. */
#define DNS_MAXNAME 1024
#define EXPAND_MAXN 20
#define ROOT_UID 0
+#define ROOT_GID 0
/* End of config.h.defaults */
diff --git a/src/src/globals.c b/src/src/globals.c
index 645cdb1..9b77d87 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -946,6 +946,7 @@ int rewrite_existflags = 0;
uschar *rfc1413_hosts = US"*";
int rfc1413_query_timeout = 5;
/* BOOL rfc821_domains = FALSE; <<< on the way out */
+uid_t root_gid = ROOT_GID;
uid_t root_uid = ROOT_UID;
router_instance *routers = NULL;
diff --git a/src/src/globals.h b/src/src/globals.h
index b036def..d66880e 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -610,6 +610,7 @@ extern int rewrite_existflags; /* Indicate which headers have rewrites *
extern uschar *rfc1413_hosts; /* RFC hosts */
extern int rfc1413_query_timeout; /* Timeout on RFC 1413 calls */
/* extern BOOL rfc821_domains; */ /* If set, syntax is 821, not 822 => being abolished */
+extern uid_t root_gid; /* The gid for root */
extern uid_t root_uid; /* The uid for root */
extern router_info routers_available[];/* Vector of available routers */
extern router_instance *routers; /* Chain of instantiated routers */
diff --git a/src/src/readconf.c b/src/src/readconf.c
index 954d546..0803058 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -2883,13 +2883,12 @@ if (!config_changed)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to stat configuration file %s",
big_buffer);
- if ((statbuf.st_uid != root_uid && /* owner not root */
- statbuf.st_uid != exim_uid /* owner not exim */
+ if ((statbuf.st_uid != root_uid /* owner not root */
#ifdef CONFIGURE_OWNER
&& statbuf.st_uid != config_uid /* owner not the special one */
#endif
) || /* or */
- (statbuf.st_gid != exim_gid /* group not exim & */
+ (statbuf.st_gid != root_gid /* group not root & */
#ifdef CONFIGURE_GROUP
&& statbuf.st_gid != config_gid /* group not the special one */
#endif
--
1.7.3.2