[exim-announce] 2 smallish security issues * To: exim-users@xxxxxxxx, exim-announce@xxxxxxxx * Subject: [exim-announce] 2 smallish security issues * From: Philip Hazel <ph10@xxxxxxxxxxxxx> * Date: Tue, 4 Jan 2005 14:54:45 +0000 (GMT) * Cc: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Two relatively minor (IMHO) security issues in Exim were raised over the Christmas break. The patches below address them for the 4.43 release. The same patches will probably easily retrofit onto quite a number of prior releases. I have also put these fixes into the current source, and made a new snapshot for testing in ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/Testing/exim-snapshot.tar.gz ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/Testing/exim-snapshot.tar.gz.sig In addition to the security patches, this snapshot contains some bug fixes and tidies that were reported by testers of the previous snapshot. Discussion of security issues - ----------------------------- 1. The function host_aton() can overflow a buffer if it is presented with an illegal IPv6 address that has more than 8 components. The input to this function is supposed to be checked; the report said that an unchecked value could be passed via the command line (without specifying which command line option, annoyingly). I found one such case, which was a call do a dnsdb lookup for a PTR record, as part of testing expansions using -be. The first patch below fixes this - as it happens, this change had already been made to the current source. The report stated that Exim was running as "exim" when the problem occurred: with -be, Exim runs as the calling user. Therefore, either the report was wrong, or there is another case that I could not find. However, if there is another case, it will now be covered by the second patch below, which puts a test into the host_aton() function itself. (This should, of course, have been there all the time, as a bit of defensive programming, but hey, I'm only human. :-) 2. The second report described a buffer overflow in the function spa_base64_to_bits(), which is part of the code for SPA authentication. This code originated in the Samba project. The overflow can be exploited only if you are using SPA authentication. The remaining patches below fix this problem by adding a buffer length parameter to the problem function. I have tested that SPA authentication still works, but I don't have the tools to test that an attempt to exploit the overflow is now detected. - -- Philip Hazel University of Cambridge Computing Service, ph10@xxxxxxxxxxxxx Cambridge, England. Phone: +44 1223 334714. - -----PATCHES------------------------------------------------------------- *** exim-4.43/src/lookups/dnsdb.c Tue Oct 5 09:32:08 2004 - --- dnsdb.c Wed Dec 29 09:36:13 2004 *************** *** 125,131 **** /* If the type is PTR, we have to construct the relevant magic lookup key. This code is now in a separate function. */ ! if (type == T_PTR) { dns_build_reverse(keystring, buffer); keystring = buffer; - --- 125,131 ---- /* If the type is PTR, we have to construct the relevant magic lookup key. This code is now in a separate function. */ ! if (type == T_PTR && string_is_ip_address(keystring, NULL)) { dns_build_reverse(keystring, buffer); keystring = buffer; *** exim-4.43/src/host.c Tue Oct 5 09:32:08 2004 - --- host.c Wed Dec 29 09:43:17 2004 *************** *** 710,721 **** if (*p == ':') p++; ! /* Split the address into components separated by colons. */ while (*p != 0) { int len = Ustrcspn(p, ":"); if (len == 0) nulloffset = ci; component[ci++] = p; p += len; if (*p == ':') p++; - --- 754,771 ---- if (*p == ':') p++; ! /* Split the address into components separated by colons. The input address ! is supposed to be checked for syntax. There was a case where this was ! overlooked; to guard against that happening again, check here and crash if ! there is a violation. */ while (*p != 0) { int len = Ustrcspn(p, ":"); if (len == 0) nulloffset = ci; + if (ci > 7) log_write(0, LOG_MAIN|LOG_PANIC_DIE, + "Internal error: invalid IPv6 address \"%s\" passed to host_aton()", + address); component[ci++] = p; p += len; if (*p == ':') p++; *** exim-4.43/src/auths/auth-spa.c Tue Oct 5 09:32:08 2004 - --- auth-spa.c Wed Dec 29 10:55:58 2004 *************** *** 404,411 **** *out = '\0'; } int ! spa_base64_to_bits (char *out, const char *in) /* base 64 to raw bytes in quasi-big-endian order, returning count of bytes */ { int len = 0; - --- 406,416 ---- *out = '\0'; } + + /* The outlength parameter was added by PH, December 2004 */ + int ! spa_base64_to_bits (char *out, int outlength, const char *in) /* base 64 to raw bytes in quasi-big-endian order, returning count of bytes */ { int len = 0; *************** *** 418,423 **** - --- 423,430 ---- do { + if (len >= outlength) /* Added by PH */ + return (-1); /* Added by PH */ digit1 = in[0]; if (DECODE64 (digit1) == BAD) return (-1); *************** *** 435,445 **** - --- 442,456 ---- ++len; if (digit3 != '=') { + if (len >= outlength) /* Added by PH */ + return (-1); /* Added by PH */ *out++ = ((DECODE64 (digit2) << 4) & 0xf0) | (DECODE64 (digit3) >> 2); ++len; if (digit4 != '=') { + if (len >= outlength) /* Added by PH */ + return (-1); /* Added by PH */ *out++ = ((DECODE64 (digit3) << 6) & 0xc0) | DECODE64 (digit4); ++len; } *** exim-4.43/src/auths/auth-spa.h Tue Oct 5 09:32:08 2004 - --- auth-spa.h Wed Dec 29 10:55:58 2004 *************** *** 9,14 **** - --- 11,19 ---- * All the code used here was torn by Marc Prud'hommeaux out of the * Samba project (by Andrew Tridgell, Jeremy Allison, and others). */ + + /* December 2004: The spa_base64_to_bits() function has no length checking in + it. I have added a check. PH */ /* It seems that some systems have existing but different definitions of some of the following types. I received a complaint about "int16" causing *************** *** 75,81 **** #define spa_request_length(ptr) (((ptr)->buffer - (uint8x*)(ptr)) + (ptr)->bufIndex) void spa_bits_to_base64 (unsigned char *, const unsigned char *, int); ! int spa_base64_to_bits(char *, const char *); void spa_build_auth_response (SPAAuthChallenge *challenge, SPAAuthResponse *response, char *user, char *password); void spa_build_auth_request (SPAAuthRequest *request, char *user, - --- 80,86 ---- #define spa_request_length(ptr) (((ptr)->buffer - (uint8x*)(ptr)) + (ptr)->bufIndex) void spa_bits_to_base64 (unsigned char *, const unsigned char *, int); ! int spa_base64_to_bits(char *, int, const char *); void spa_build_auth_response (SPAAuthChallenge *challenge, SPAAuthResponse *response, char *user, char *password); void spa_build_auth_request (SPAAuthRequest *request, char *user, *** exim-4.43/src/auths/spa.c Tue Oct 5 09:32:08 2004 - --- spa.c Wed Dec 29 10:55:58 2004 *************** *** 133,139 **** return FAIL; } ! if (spa_base64_to_bits((char *)(&request), (const char *)(data)) < 0) { DEBUG(D_auth) debug_printf("auth_spa_server(): bad base64 data in " "request: %s\n", data); - --- 135,141 ---- return FAIL; } ! if (spa_base64_to_bits((char *)(&request), sizeof(request), (const char *)(data)) < 0) { DEBUG(D_auth) debug_printf("auth_spa_server(): bad base64 data in " "request: %s\n", data); *************** *** 153,159 **** } /* dump client response */ ! if (spa_base64_to_bits((char *)(&response), (const char *)(data)) < 0) { DEBUG(D_auth) debug_printf("auth_spa_server(): bad base64 data in " "response: %s\n", data); - --- 155,161 ---- } /* dump client response */ ! if (spa_base64_to_bits((char *)(&response), sizeof(response), (const char *)(data)) < 0) { DEBUG(D_auth) debug_printf("auth_spa_server(): bad base64 data in " "response: %s\n", data); *************** *** 319,325 **** /* convert the challenge into the challenge struct */ DSPA("\n\n%s authenticator: challenge (%s)\n\n", ablock->name, buffer + 4); ! spa_base64_to_bits ((char *)(&challenge), (const char *)(buffer + 4)); spa_build_auth_response (&challenge, &response, CS username, CS password); - --- 324,330 ---- /* convert the challenge into the challenge struct */ DSPA("\n\n%s authenticator: challenge (%s)\n\n", ablock->name, buffer + 4); ! spa_base64_to_bits ((char *)(&challenge), sizeof(challenge), (const char *)(buffer + 4)); spa_build_auth_response (&challenge, &response, CS username, CS password); -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.6 (GNU/Linux) iQEVAwUBQdqtFZdm4IT7D0PYAQLJmggAkP/M32D3FsbnqBZGxMIRsEFOufoBrw4I oX3arosSvCdS/3cb39YEs2rOQjfJUeHvaxmmu6AN+3X01OZCfsmY7JL6RamowQlV IBvLipMLQ8qEuUGhwRiNXYE1jxJm6rmbQLJHWukgEtmXO5GjGWe+jjCKR0jjNw/u m75TbZCDmtz0nVB+/0yam9teSAbIoIEER9xtpaM8vjRLCptXOzwifOVUOZQzIwxr vC/UqcCSoa1CAAaAHPbNisemPfUa6d+WBd9/W74L7v5AcZ6Tk1wbVqoXuFV3c8yP TiUqxWTudhVbvC5KIHXoV/PhqVExWTJM4ggUZ23y5tZ0mrDDJkFqGw== =vdDU -----END PGP SIGNATURE-----
peitolm, pfeifer: pls verify and apply patches ___ http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0021 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0022 http://secunia.com/advisories/13713/ http://securitytracker.com/alerts/2005/Jan/1012771.html
Just as I was going to mark 4.43 stable,Will patch, test and fix tomorrow, hopefully Philip will release a new version soon.
exim-4.43-r2 seems to be the patched version arches please test and mark stable current KEYWORDS="~x86 ~sparc ~hppa ~alpha ~amd64 ~ia64" target KEYWORDS="x86 sparc hppa alpha amd64 ~ia64"
A few CANs for you : CAN-2005-0021 Buffer overflow in the host_aton function via cmdln option CAN-2005-0022 Buffer overflow in the spa_base64_to_bits function
I will mark stable on x86 and sparc when I'm happy it is stable, could other archs please test and add ~<arch> I plan to bump to stable in just over 24Hrs time.
Stable on hppa.
Alpha looks good.
AMD64 stable.
ppc needs this stable too
marking stable on x86, sparc, hppa, alpha, amd64, ppc.
ia64 should add ~ia64 KEYWORD. Ready for GLSA
GLSA 200501-23 ia64, dont't forget to add the keyword to benefit from the GLSA
*** Bug 81134 has been marked as a duplicate of this bug. ***