On 2014-06-21, Otto Moerbeek <o...@drijf.net> wrote: > > This is a know bug. If an unknown user tries to log in, the login code > goes into a loop expanding a buffer until it runs out of mem. The > cause of the bug is also known, but nobody (including myself) came up > with a diff yet.
To be clear: this is fixed in libc but it's a post-5.5 change - when Otto says that nobody came up with a diff, he's talking about a diff to have dovecot cope with the old libc code. The relevant libc commit (below) should apply directly to a 5.5 system. Also note that you can use a separate passwd-like file for dovecot authentication, which is not affected by this bug, so you can work around it without configuring ldap/sql. (Personally I like to use different passwords for email and login accounts so I do this anyway..) --------------------- PatchSet 5269 Date: 2014/03/05 23:44:47 Author: schwarze Branch: HEAD Tag: (none) Log: Fix the return values of getpwnam_r(), getpwuid_r(), getgrnam_r(), and getgrgid_r() to agree with POSIX. Not touching errno handling yet, which will also need fixing. Problem originally reported by william at 25thandClement dot com on bugs@. OK sthen@, and kettenis@ agrees it's "a step in the right direction". Members: gen/getgrent.c:1.38->1.39 gen/getpwent.c:1.48->1.49 Index: src/lib/libc/gen/getgrent.c diff -u src/lib/libc/gen/getgrent.c:1.38 src/lib/libc/gen/getgrent.c:1.39 --- src/lib/libc/gen/getgrent.c:1.38 Wed Apr 17 17:40:35 2013 +++ src/lib/libc/gen/getgrent.c Wed Mar 5 23:44:47 2014 @@ -1,4 +1,4 @@ -/* $OpenBSD: getgrent.c,v 1.38 2013/04/17 17:40:35 tedu Exp $ */ +/* $OpenBSD: getgrent.c,v 1.39 2014/03/05 23:44:47 schwarze Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -134,6 +134,7 @@ if (bufsize < GETGR_R_SIZE_MAX) return ERANGE; errnosave = errno; + errno = 0; *result = getgrnam_gs(name, grp, (struct group_storage *)buffer); if (*result == NULL) ret = errno; @@ -180,6 +181,7 @@ if (bufsize < GETGR_R_SIZE_MAX) return ERANGE; errnosave = errno; + errno = 0; *result = getgrgid_gs(gid, grp, (struct group_storage *)buffer); if (*result == NULL) ret = errno; Index: src/lib/libc/gen/getpwent.c diff -u src/lib/libc/gen/getpwent.c:1.48 src/lib/libc/gen/getpwent.c:1.49 --- src/lib/libc/gen/getpwent.c:1.48 Fri Nov 15 22:32:55 2013 +++ src/lib/libc/gen/getpwent.c Wed Mar 5 23:44:47 2014 @@ -1,4 +1,4 @@ -/* $OpenBSD: getpwent.c,v 1.48 2013/11/15 22:32:55 benno Exp $ */ +/* $OpenBSD: getpwent.c,v 1.49 2014/03/05 23:44:47 schwarze Exp $ */ /* * Copyright (c) 2008 Theo de Raadt * Copyright (c) 1988, 1993 @@ -708,8 +708,12 @@ { struct passwd *pwret = NULL; int flags = 0, *flagsp; + int my_errno = 0; + int saved_errno; _THREAD_PRIVATE_MUTEX_LOCK(pw); + saved_errno = errno; + errno = 0; if (!_pw_db && !__initdb()) goto fail; @@ -733,8 +737,12 @@ fail: if (pwretp) *pwretp = pwret; + if (pwret == NULL) + my_errno = errno; + if (!errno) + errno = saved_errno; _THREAD_PRIVATE_MUTEX_UNLOCK(pw); - return (pwret ? 0 : 1); + return (my_errno); } struct passwd * @@ -753,8 +761,12 @@ { struct passwd *pwret = NULL; int flags = 0, *flagsp; + int my_errno = 0; + int saved_errno; _THREAD_PRIVATE_MUTEX_LOCK(pw); + saved_errno = errno; + errno = 0; if (!_pw_db && !__initdb()) goto fail; @@ -778,8 +790,12 @@ fail: if (pwretp) *pwretp = pwret; + if (pwret == NULL) + my_errno = errno; + if (!errno) + errno = saved_errno; _THREAD_PRIVATE_MUTEX_UNLOCK(pw); - return (pwret ? 0 : 1); + return (my_errno); } struct passwd *