dovecot-2.2: auth: Refuse to run checkpassword script insecurely...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Oct 26 19:11:48 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/a13098b642e9
changeset: 16887:a13098b642e9
user: Timo Sirainen <tss at iki.fi>
date: Sat Oct 26 19:11:34 2013 +0300
description:
auth: Refuse to run checkpassword script insecurely by default
diffstat:
src/auth/checkpassword-reply.c | 27 ++++++++++++++++++++++++++-
src/auth/db-checkpassword.c | 1 +
2 files changed, 27 insertions(+), 1 deletions(-)
diffs (54 lines):
diff -r 26355654c314 -r a13098b642e9 src/auth/checkpassword-reply.c
--- a/src/auth/checkpassword-reply.c Sat Oct 26 18:59:52 2013 +0300
+++ b/src/auth/checkpassword-reply.c Sat Oct 26 19:11:34 2013 +0300
@@ -11,13 +11,38 @@
int main(void)
{
string_t *str;
- const char *user, *home, *authorized;
+ const char *user, *home, *authorized, *orig_uid;
const char *extra_env, *key, *value, *const *tmp;
bool uid_found = FALSE, gid_found = FALSE;
lib_init();
str = t_str_new(1024);
+ orig_uid = getenv("ORIG_UID");
+ /* ORIG_UID should have the auth process's UID that forked us.
+ if the checkpassword changed the UID, this could be a security hole
+ because the UID's other processes can ptrace this process and write
+ any kind of a reply to fd 4. so we can run only if:
+
+ a) INSECURE_SETUID environment is set.
+ b) process isn't ptraceable (this binary is setuid/setgid)
+ c) checkpassword didn't actually change the UID (but used
+ userdb_uid instead)
+ */
+ if (getenv("INSECURE_SETUID") == NULL &&
+ (orig_uid == NULL || strtoul(orig_uid, NULL, 10) != getuid()) &&
+ getuid() == geteuid() && getgid() == getegid()) {
+ if (orig_uid == NULL) {
+ i_error("checkpassword: ORIG_UID environment was dropped by checkpassword. "
+ "Can't verify if we're safe to run. See "
+ "http://wiki2.dovecot.org/AuthDatabase/CheckPassword#Security");
+ } else {
+ i_error("checkpassword: The checkpassword couldn't be run securely. See "
+ "http://wiki2.dovecot.org/AuthDatabase/CheckPassword#Security");
+ }
+ return 111;
+ }
+
user = getenv("USER");
if (user != NULL) {
if (strchr(user, '\t') != NULL) {
diff -r 26355654c314 -r a13098b642e9 src/auth/db-checkpassword.c
--- a/src/auth/db-checkpassword.c Sat Oct 26 18:59:52 2013 +0300
+++ b/src/auth/db-checkpassword.c Sat Oct 26 19:11:34 2013 +0300
@@ -251,6 +251,7 @@
pipe, also pass some other possibly interesting information
via environment. Use UCSPI names for local/remote IPs. */
env_put("PROTO=TCP"); /* UCSPI */
+ env_put(t_strdup_printf("ORIG_UID=%s", dec2str(getuid())));
env_put(t_strconcat("SERVICE=", request->service, NULL));
if (request->local_ip.family != 0) {
env_put(t_strconcat("TCPLOCALIP=",
More information about the dovecot-cvs
mailing list