[Dovecot] Segfault with passwd as a second userdb at auth_fields_rollback

Jan Kończak jkonczak at astronet.pl
Sun May 11 14:56:26 UTC 2014


Hello,

I've been trying to set up dovecot to support passwd-file + passwd/PAM auth.

I made an unusual config (passwd-file as userdb failed to work for me), which 
uses static as userdb:

===============
passdb {
  driver = passwd-file
  args = username_format=%u scheme=CRYPT /etc/dovecot/users
}
userdb {
  driver = static
  default_fields = uid=vmail gid=vmail home=/var/spool/mail/%d/%n
}
passdb {
  driver = pam
}
userdb {
  driver = passwd
}
===============

While passwd-file+static worked well, passwd/PAM caused trouble:

$ doveadm user xxx
doveadm(root): Error: userdb lookup(xxx): Disconnected unexpectedly
field   value

If passwd-file had the user, check went fine; otherwise it segfaulted.

The crash has been accompanied by a syslog message: 
kernel: auth[9788]: segfault at 18 ip 0000000000416391 sp 00007fffd11a3d90 
error 4 in auth[400000+44000]

Translating address lead me to:
0000000000416390 <auth_fields_rollback>:
  416390:       53                      push   %rbx
  416391:       48 83 7f 18 00          cmpq   $0x0,0x18(%rdi)

I was using packages from http://packages.atrpms.net/dist/el6/dovecot/
To be precise, dovecot-2.2.10-1_14.el6.x86_64.rpm

I tampered with the src.rpm, upgraded spec&sources to match 2.2.12.
It didn't help, so I tries to "workaround" this.

The bug has gone when in src/auth/auth-fields.c:210 I added check if the field 
ptr is not null. As it's a userdb query, it seems that for some reason 
(static?) in src/auth/auth-request.c:1058 the function auth_fields_rollback is 
called with null request->userdb_reply

Now it works fine:

$ doveadm user xxx
field   value
uid     1000
gid     100
home    /home/xxx
mail    maildir:~/.maildir
system_groups_user      xxx

$ doveadm user jkonczak at ast...
field   value
uid     103
gid     103
home    /var/spool/mail/ast.../jkonczak
mail    maildir:~/.maildir

So now virtual users get vmail uid/gid, system users get their uid/gid, home 
is fine etc.

Below I attach the patch + full config.

Regards,
Jan Kończak


===============================================
$ cat SOURCES/dovecot-2.2.12-auth_fields_rollback-nullptr_check.patch
--- src/auth/auth-fields.c.orig 2014-05-11 16:17:49.755258666 +0200
+++ src/auth/auth-fields.c      2014-05-11 16:18:24.704946586 +0200
@@ -207,6 +207,7 @@

 void auth_fields_rollback(struct auth_fields *fields)
 {
+       if (fields==NULL) return;
        if (array_is_created(&fields->snapshot_fields)) {
                array_clear(&fields->fields);
                array_append_array(&fields->fields, &fields->snapshot_fields);
===============================================
$ dovecot --version
2.2.12
$ doveconf   # passdb/userdb/auth related 
passdb {
  args = username_format=%u scheme=CRYPT /etc/dovecot/users
  default_fields =
  deny = no
  driver = passwd-file
  master = no
  override_fields =
  pass = no
  result_failure = continue
  result_internalfail = continue
  result_success = return-ok
  skip = never
} 
passdb {
  args =
  default_fields =
  deny = no
  driver = pam
  master = no
  override_fields =
  pass = no
  result_failure = continue
  result_internalfail = continue
  result_success = return-ok
  skip = never
} 
service auth {
  chroot =
  client_limit = 0
  drop_priv_before_exec = no
  executable = auth
  extra_groups =
  group =
  idle_kill = 0
  privileged_group =
  process_limit = 1
  process_min_avail = 0
  protocol =
  service_count = 0
  type =
  unix_listener /var/spool/postfix/private/auth {
    group = postfix
    mode = 0660
    user = postfix
  }
  unix_listener auth-client {
    group =
    mode = 0600
    user = $default_internal_user
  }
  unix_listener auth-login {
    group =
    mode = 0600
    user = $default_internal_user
  }
  unix_listener auth-master {
    group =
    mode = 0600
    user =
  }
  unix_listener auth-userdb {
    group =
    mode = 0666
    user = $default_internal_user
  }
  unix_listener login/login {
    group =
    mode = 0666
    user =
  }
  unix_listener token-login/tokenlogin {
    group =
    mode = 0666
    user =
  }
  user = $default_internal_user
  vsz_limit = 18446744073709551615 B
}
userdb {
  args = 
  default_fields = uid=vmail gid=vmail home=/var/spool/mail/%d/%n
  driver = static
  override_fields = 
  result_failure = continue
  result_internalfail = continue
  result_success = return-ok
  skip = never
}
userdb {
  args = 
  default_fields = 
  driver = passwd
  override_fields = 
  result_failure = continue
  result_internalfail = continue
  result_success = return-ok
  skip = never
}
===============================================


More information about the dovecot mailing list