On 2014-06-21, Otto Moerbeek <[email protected]> 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 *