Back-patch upstream 8.2-branch fix for blowfish signed-character bug (CVE-2011-2483). http://git.postgresql.org/gitweb/?p=postgresql.git&a=commitdiff&h=457c2d9158d35240ec54ea2052d89ff4f8fe19db diff -Naur postgresql-8.1.23.orig/contrib/pgcrypto/crypt-blowfish.c postgresql-8.1.23/contrib/pgcrypto/crypt-blowfish.c --- postgresql-8.1.23.orig/contrib/pgcrypto/crypt-blowfish.c 2010-12-13 22:52:30.000000000 -0500 +++ postgresql-8.1.23/contrib/pgcrypto/crypt-blowfish.c 2011-09-27 11:20:52.736242179 -0400 @@ -3,8 +3,8 @@ * and crypt(3) interfaces added, but optimizations specific to password * cracking removed. * - * Written by Solar Designer <solar@openwall.com> in 1998-2001, and placed - * in the public domain. + * Written by Solar Designer <solar at openwall.com> in 1998-2002 and + * placed in the public domain. * * There's absolutely no warranty. * @@ -17,9 +17,9 @@ * of your choice. * * This implementation is compatible with OpenBSD bcrypt.c (version 2a) - * by Niels Provos <provos@physnet.uni-hamburg.de>, and uses some of his - * ideas. The password hashing algorithm was designed by David Mazieres - * <dm@lcs.mit.edu>. + * by Niels Provos <provos at citi.umich.edu>, and uses some of his + * ideas. The password hashing algorithm was designed by David Mazieres + * <dm at lcs.mit.edu>. * * There's a paper on the algorithm that explains its design decisions: * @@ -38,7 +38,7 @@ #ifdef __i386__ #define BF_ASM 0 /* 1 */ #define BF_SCALE 1 -#elif defined(__alpha__) +#elif defined(__x86_64__) || defined(__alpha__) || defined(__hppa__) #define BF_ASM 0 #define BF_SCALE 1 #else @@ -47,6 +47,7 @@ #endif typedef unsigned int BF_word; +typedef signed int BF_word_signed; /* Number of Blowfish rounds, this is also hardcoded into a few places */ #define BF_N 16 @@ -542,7 +543,8 @@ #endif static void -BF_set_key(const char *key, BF_key expanded, BF_key initial) +BF_set_key(const char *key, BF_key expanded, BF_key initial, + int sign_extension_bug) { const char *ptr = key; int i, @@ -555,7 +557,10 @@ for (j = 0; j < 4; j++) { tmp <<= 8; - tmp |= *ptr; + if (sign_extension_bug) + tmp |= (BF_word_signed) (signed char) *ptr; + else + tmp |= (unsigned char) *ptr; if (!*ptr) ptr = key; @@ -597,10 +602,11 @@ if (setting[0] != '$' || setting[1] != '2' || - setting[2] != 'a' || + (setting[2] != 'a' && setting[2] != 'x') || setting[3] != '$' || setting[4] < '0' || setting[4] > '3' || setting[5] < '0' || setting[5] > '9' || + (setting[4] == '3' && setting[5] > '1') || setting[6] != '$') { return NULL; @@ -614,7 +620,7 @@ } BF_swap(data.binary.salt, 4); - BF_set_key(key, data.expanded_key, data.ctx.P); + BF_set_key(key, data.expanded_key, data.ctx.P, setting[2] == 'x'); memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); diff -Naur postgresql-8.1.23.orig/contrib/pgcrypto/px-crypt.c postgresql-8.1.23/contrib/pgcrypto/px-crypt.c --- postgresql-8.1.23.orig/contrib/pgcrypto/px-crypt.c 2010-12-13 22:52:30.000000000 -0500 +++ postgresql-8.1.23/contrib/pgcrypto/px-crypt.c 2011-09-27 11:20:52.737242045 -0400 @@ -79,6 +79,7 @@ static const struct px_crypt_algo px_crypt_list[] = { {"$2a$", 4, run_crypt_bf}, + {"$2x$", 4, run_crypt_bf}, {"$2$", 3, NULL}, /* N/A */ {"$1$", 3, run_crypt_md5}, {"_", 1, run_crypt_des},