On Sun, Jun 22, 2014 at 05:01:38AM +0200, J??r??mie Courr??ges-Anglas wrote: > > (Redirecting this to ports@) > > Could you folks test this patch against dovecot from -stable? I only > did compile testing on -current. I don't know how the allocator(s) > handle failures nor how would i_realloc handle pwbuf_size == > old_pwbuf_size, but this looks safe. > > > $OpenBSD$ > > Hack: we avoid the actual ERANGE error case by always providing a large > enough buffer.
I'd prefer to use the diff I had commited when this issue first came up although back then local auth didn't work at all without the hack that was added. I don't have a 5.5 system around at the moment so please check this builds first and then test as appropriate. Index: Makefile =================================================================== RCS file: /home/cvs/ports/mail/dovecot/Makefile,v retrieving revision 1.218.2.1 diff -u -p -u -p -r1.218.2.1 Makefile --- Makefile 12 May 2014 09:40:19 -0000 1.218.2.1 +++ Makefile 22 Jun 2014 08:34:15 -0000 @@ -20,7 +20,7 @@ PKGNAME-postgresql= dovecot-postgresql-$ CATEGORIES= mail MASTER_SITES= ${HOMEPAGE}releases/${V_MAJOR}/ -REVISION-server= 0 +REVISION-server= 1 SHARED_LIBS= dovecot-compression 0.0 \ dovecot-lda 2.0 \ Index: patches/patch-src_lib_ipwd_c =================================================================== RCS file: patches/patch-src_lib_ipwd_c diff -N patches/patch-src_lib_ipwd_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_lib_ipwd_c 22 Jun 2014 09:32:58 -0000 @@ -0,0 +1,129 @@ +$OpenBSD$ + +Revert http://hg.dovecot.org/dovecot-2.2/raw-rev/349d52c4ca51 to workaround +non POSIX compliant getpwnam_r / getpwuid_r functions. + +--- src/lib/ipwd.c.orig Tue Nov 19 15:36:30 2013 ++++ src/lib/ipwd.c Sun Jun 22 05:30:14 2014 +@@ -6,33 +6,41 @@ + + #include <unistd.h> + +-#define PWBUF_MIN_SIZE 128 +-#define GRBUF_MIN_SIZE 128 ++#define DEFAULT_PWBUF_SIZE 16384 ++#define DEFAULT_GRBUF_SIZE 16384 + + static void *pwbuf = NULL, *grbuf = NULL; + static size_t pwbuf_size, grbuf_size; + + static void pw_init(void) + { +- size_t old_pwbuf_size = pwbuf_size; ++ long size; + +- if (pwbuf == NULL || errno == ERANGE) { +- pwbuf_size = nearest_power(old_pwbuf_size + 1); +- if (pwbuf_size < PWBUF_MIN_SIZE) +- pwbuf_size = PWBUF_MIN_SIZE; +- pwbuf = i_realloc(pwbuf, old_pwbuf_size, pwbuf_size); ++ if (pwbuf == NULL) { ++ size = sysconf(_SC_GETPW_R_SIZE_MAX); ++ if (size < 0) ++ size = DEFAULT_PWBUF_SIZE; ++ ++ pwbuf_size = size; ++ pwbuf = i_malloc(pwbuf_size); + } + } + + static void gr_init(void) + { +- size_t old_grbuf_size = grbuf_size; ++ long size; + +- if (grbuf == NULL || errno == ERANGE) { +- grbuf_size = nearest_power(old_grbuf_size + 1); +- if (grbuf_size < PWBUF_MIN_SIZE) +- grbuf_size = PWBUF_MIN_SIZE; +- grbuf = i_realloc(grbuf, old_grbuf_size, grbuf_size); ++ if (grbuf == NULL) { ++ size = sysconf(_SC_GETGR_R_SIZE_MAX); ++ /* Some BSDs return too low value for this. instead of trying ++ to figure out exactly which, just make sure it's at least ++ a reasonable size. if the real size is smaller, it doesn't ++ matter much that we waste a few kilobytes of memory. */ ++ if (size < DEFAULT_GRBUF_SIZE) ++ size = DEFAULT_GRBUF_SIZE; ++ ++ grbuf_size = size; ++ grbuf = i_malloc(grbuf_size); + } + } + +@@ -46,16 +54,8 @@ int i_getpwnam(const char *name, struct passwd *pwd_r) + { + struct passwd *result; + +- errno = 0; +- do { +- pw_init(); +- errno = getpwnam_r(name, pwd_r, pwbuf, pwbuf_size, &result); +-#ifdef __OpenBSD__ +- /* OpenBSD returns 1 for all errors, assume it's ERANGE */ +- if (errno == 1) +- errno = ERANGE; +-#endif +- } while (errno == ERANGE); ++ pw_init(); ++ errno = getpwnam_r(name, pwd_r, pwbuf, pwbuf_size, &result); + if (result != NULL) + return 1; + if (errno == EINVAL) { +@@ -69,16 +69,8 @@ int i_getpwuid(uid_t uid, struct passwd *pwd_r) + { + struct passwd *result; + +- errno = 0; +- do { +- pw_init(); +- errno = getpwuid_r(uid, pwd_r, pwbuf, pwbuf_size, &result); +-#ifdef __OpenBSD__ +- /* OpenBSD returns 1 for all errors, assume it's ERANGE */ +- if (errno == 1) +- errno = ERANGE; +-#endif +- } while (errno == ERANGE); ++ pw_init(); ++ errno = getpwuid_r(uid, pwd_r, pwbuf, pwbuf_size, &result); + if (result != NULL) + return 1; + return errno == 0 ? 0 : -1; +@@ -88,11 +80,8 @@ int i_getgrnam(const char *name, struct group *grp_r) + { + struct group *result; + +- errno = 0; +- do { +- gr_init(); +- errno = getgrnam_r(name, grp_r, grbuf, grbuf_size, &result); +- } while (errno == ERANGE); ++ gr_init(); ++ errno = getgrnam_r(name, grp_r, grbuf, grbuf_size, &result); + if (result != NULL) + return 1; + return errno == 0 ? 0 : -1; +@@ -102,11 +91,8 @@ int i_getgrgid(gid_t gid, struct group *grp_r) + { + struct group *result; + +- errno = 0; +- do { +- gr_init(); +- errno = getgrgid_r(gid, grp_r, grbuf, grbuf_size, &result); +- } while (errno == ERANGE); ++ gr_init(); ++ errno = getgrgid_r(gid, grp_r, grbuf, grbuf_size, &result); + if (result != NULL) + return 1; + return errno == 0 ? 0 : -1; -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.