From f87d745aaa175ea72a839c385c4c48ef232a5425 Mon Sep 17 00:00:00 2001 From: taca Date: Wed, 22 Jun 2011 09:54:35 +0000 Subject: Improve previous security fix for cyrpt_blowfish(). There was incompatible result by previous fix and it should be gone away. Beside ths security fix, ${PREFIX}/bin/phar.phar has correct shbang line. Bump PKGREVISION. --- lang/php53/patches/patch-af | 11 +- .../patches/patch-ext_standard_crypt__blowfish.c | 150 ++++++++++++++++++++- 2 files changed, 157 insertions(+), 4 deletions(-) (limited to 'lang/php53/patches') diff --git a/lang/php53/patches/patch-af b/lang/php53/patches/patch-af index 8ca11c4eaca..c06b90d9d76 100644 --- a/lang/php53/patches/patch-af +++ b/lang/php53/patches/patch-af @@ -1,7 +1,16 @@ -$NetBSD: patch-af,v 1.2 2011/03/19 07:01:19 taca Exp $ +$NetBSD: patch-af,v 1.3 2011/06/22 09:54:35 taca Exp $ --- ext/phar/Makefile.frag.orig 2011-02-25 09:32:17.000000000 +0000 +++ ext/phar/Makefile.frag +@@ -18,7 +18,7 @@ PHP_PHARCMD_EXECUTABLE = ` \ + else \ + $(top_srcdir)/build/shtool echo -n -- "$(PHP_EXECUTABLE)"; \ + fi;` +-PHP_PHARCMD_BANG = `$(top_srcdir)/build/shtool echo -n -- "$(INSTALL_ROOT)$(bindir)/$(program_prefix)php$(program_suffix)$(EXEEXT)";` ++PHP_PHARCMD_BANG = `$(top_srcdir)/build/shtool echo -n -- "$(bindir)/$(program_prefix)php$(program_suffix)$(EXEEXT)";` + + $(builddir)/phar/phar.inc: $(srcdir)/phar/phar.inc + -@test -d $(builddir)/phar || mkdir $(builddir)/phar @@ -39,4 +39,4 @@ install-pharcmd: pharcmd -@$(mkinstalldirs) $(INSTALL_ROOT)$(bindir) $(INSTALL) $(builddir)/phar.phar $(INSTALL_ROOT)$(bindir) diff --git a/lang/php53/patches/patch-ext_standard_crypt__blowfish.c b/lang/php53/patches/patch-ext_standard_crypt__blowfish.c index 0e6d346facc..f8ea74092ea 100644 --- a/lang/php53/patches/patch-ext_standard_crypt__blowfish.c +++ b/lang/php53/patches/patch-ext_standard_crypt__blowfish.c @@ -1,16 +1,160 @@ -$NetBSD: patch-ext_standard_crypt__blowfish.c,v 1.1 2011/06/20 13:38:19 taca Exp $ +$NetBSD: patch-ext_standard_crypt__blowfish.c,v 1.2 2011/06/22 09:54:35 taca Exp $ - Fix potential security problem by char signedness processing: http://www.openwall.com/lists/oss-security/2011/06/20/2 + Dereived from revision 1.11 change of http://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/glibc/crypt_blowfish/crypt_blowfish.c. + --- ext/standard/crypt_blowfish.c.orig 2010-02-21 23:47:14.000000000 +0000 +++ ext/standard/crypt_blowfish.c -@@ -565,7 +565,7 @@ static void BF_set_key(__CONST char *key +@@ -7,6 +7,7 @@ + * cracking removed. + * + * Written by Solar Designer in 1998-2002 and ++ * placed in the public domain. Quick self-test added in 2011 and also + * placed in the public domain. + * + * There's absolutely no warranty. +@@ -51,6 +52,13 @@ + #define __CONST __const + #endif + ++/* ++ * Please keep this enabled. We really don't want incompatible hashes to be ++ * produced. The performance cost of this quick self-test is around 0.6% at ++ * the "$2a$08" setting. ++ */ ++#define BF_SELF_TEST ++ + #ifdef __i386__ + #define BF_ASM 0 + #define BF_SCALE 1 +@@ -63,6 +71,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 +@@ -555,7 +564,8 @@ static void BF_swap(BF_word *x, int coun + } while (ptr < &data.ctx.S[3][0xFF]); + #endif + +-static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) ++static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial, ++ int sign_extension_bug) + { + __CONST char *ptr = key; + int i, j; +@@ -565,7 +575,10 @@ static void BF_set_key(__CONST char *key tmp = 0; for (j = 0; j < 4; j++) { tmp <<= 8; - tmp |= *ptr; -+ tmp |= (unsigned char)*ptr; ++ if (sign_extension_bug) ++ tmp |= (BF_word_signed)(signed char)*ptr; ++ else ++ tmp |= (unsigned char)*ptr; if (!*ptr) ptr = key; else ptr++; } +@@ -575,8 +588,9 @@ static void BF_set_key(__CONST char *key + } + } + +-char *php_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, +- char *output, int size) ++static char *BF_crypt(__CONST char *key, __CONST char *setting, ++ char *output, int size, ++ BF_word min) + { + #if BF_ASM + extern void _BF_body_r(BF_ctx *ctx); +@@ -602,7 +616,7 @@ char *php_crypt_blowfish_rn(__CONST char + + 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' || +@@ -613,7 +627,7 @@ char *php_crypt_blowfish_rn(__CONST char + } + + count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); +- if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { ++ if (count < min || BF_decode(data.binary.salt, &setting[7], 16)) { + clean(data.binary.salt, sizeof(data.binary.salt)); + __set_errno(EINVAL); + return NULL; +@@ -621,7 +635,7 @@ char *php_crypt_blowfish_rn(__CONST char + + 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)); + +@@ -721,14 +735,59 @@ char *php_crypt_blowfish_rn(__CONST char + BF_encode(&output[7 + 22], data.binary.output, 23); + output[7 + 22 + 31] = '\0'; + ++#ifndef BF_SELF_TEST + /* Overwrite the most obvious sensitive data we have on the stack. Note + * that this does not guarantee there's no sensitive data left on the + * stack and/or in registers; I'm not aware of portable code that does. */ + clean(&data, sizeof(data)); ++#endif + + return output; + } + ++char *php_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, ++ char *output, int size) ++{ ++#ifdef BF_SELF_TEST ++ __CONST char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8"; ++ __CONST char *test_2a = ++ "$2a$00$abcdefghijklmnopqrstuui1D709vfamulimlGcq0qq3UvuUasvEa" ++ "\0" ++ "canary"; ++ __CONST char *test_2x = ++ "$2x$00$abcdefghijklmnopqrstuuVUrPmXD6q/nVSSp7pNDhCR9071IfIRe" ++ "\0" ++ "canary"; ++ __CONST char *test_hash, *p; ++ int ok; ++ char buf[7 + 22 + 31 + 1 + 6 + 1]; ++ ++ output = BF_crypt(key, setting, output, size, 16); ++ ++/* Do a quick self-test. This also happens to overwrite BF_crypt()'s data. */ ++ test_hash = (setting[2] == 'x') ? test_2x : test_2a; ++ memcpy(buf, test_hash, sizeof(buf)); ++ memset(buf, -1, sizeof(buf) - (6 + 1)); /* keep "canary" only */ ++ p = BF_crypt(test_key, test_hash, buf, sizeof(buf) - 6, 1); ++ ++ ok = (p == buf && !memcmp(p, test_hash, sizeof(buf))); ++ ++/* This could reveal what hash type we were using last. Unfortunately, we ++ * can't reliably clean the test_hash pointer. */ ++ clean(&buf, sizeof(buf)); ++ ++ if (ok) ++ return output; ++ ++/* Should not happen */ ++ __set_errno(EINVAL); /* pretend we don't support this hash type */ ++ return NULL; ++#else ++#warning Self-test is disabled, please enable ++ return BF_crypt(key, setting, output, size, 16); ++#endif ++} ++ + char *php_crypt_gensalt_blowfish_rn(unsigned long count, + __CONST char *input, int size, char *output, int output_size) + { -- cgit v1.2.3