diff -u php5-5.3.2/debian/changelog php5-5.3.2/debian/changelog --- php5-5.3.2/debian/changelog +++ php5-5.3.2/debian/changelog @@ -1,3 +1,24 @@ +php5 (5.3.2-1ubuntu4.18) lucid-security; urgency=low + + * SECURITY UPDATE: HTTP response-splitting issue with %0D sequences + - debian/patches/CVE-2011-1398.patch: properly handle %0D and NUL in + main/SAPI.c, added tests to ext/standard/tests/*, fix test suite + failures in ext/phar/phar_object.c. + - CVE-2011-1398 + - CVE-2012-4388 + * SECURITY UPDATE: denial of service and possible code execution via + _php_stream_scandir function (LP: #1028064) + - debian/patches/CVE-2012-2688.patch: prevent overflow in + main/streams/streams.c. + - CVE-2012-2688 + * SECURITY UPDATE: denial of service via PDO extension crafted parameter + - debian/patches/CVE-2012-3450.patch: improve logic in + ext/pdo/pdo_sql_parser.re, regenerate ext/pdo/pdo_sql_parser.c, add + test to ext/pdo_mysql/tests/bug_61755.phpt. + - CVE-2012-3450 + + -- Marc Deslauriers Wed, 12 Sep 2012 11:33:30 -0400 + php5 (5.3.2-1ubuntu4.17) lucid-security; urgency=low * SECURITY UPDATE: denial of service via invalid tidy objects diff -u php5-5.3.2/debian/patches/series php5-5.3.2/debian/patches/series --- php5-5.3.2/debian/patches/series +++ php5-5.3.2/debian/patches/series @@ -108,0 +109,3 @@ +CVE-2011-1398.patch +CVE-2012-2688.patch +CVE-2012-3450.patch only in patch2: unchanged: --- php5-5.3.2.orig/debian/patches/CVE-2011-1398.patch +++ php5-5.3.2/debian/patches/CVE-2011-1398.patch @@ -0,0 +1,160 @@ +Description: fix HTTP response-splitting issue with %0D sequences +Origin: upstream, http://git.php.net/?p=php-src.git;a=commit;h=61088ce7296f2a3b4b53e60bdf413455b870664d +Origin: upstream, http://git.php.net/?p=php-src.git;a=commit;h=8e82bda330264d290a5e55580eea2eb875d4cb69 +Origin: upstream, http://git.php.net/?p=php-src.git;a=commit;h=ca58cd01fc329f907a13b82370427715d9c5bf70 +Origin: upstream, http://git.php.net/?p=php-src.git;a=commit;h=daa190f8fd5441b077bfd5ae8e999596a8c34dd3 +Bug: https://bugs.php.net/bug.php?id=60227 + +Index: php5-5.3.5/ext/standard/tests/general_functions/bug60227_1.phpt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ php5-5.3.5/ext/standard/tests/general_functions/bug60227_1.phpt 2012-09-12 09:10:30.533070464 -0400 +@@ -0,0 +1,20 @@ ++--TEST-- ++Bug #60227 (header() cannot detect the multi-line header with CR) ++--FILE-- ++ ++--EXPECTF-- ++Warning: Header may not contain more than a single header, new line detected in %s on line %d ++foo ++--EXPECTHEADERS-- ++X-Foo1: a ++X-Foo2: b ++X-Foo3: c ++X-Foo4: d ++ +Index: php5-5.3.5/ext/standard/tests/general_functions/bug60227_2.phpt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ php5-5.3.5/ext/standard/tests/general_functions/bug60227_2.phpt 2012-09-12 09:10:30.533070464 -0400 +@@ -0,0 +1,14 @@ ++--TEST-- ++Bug #60227 (header() cannot detect the multi-line header with CR), \r before \n ++--FILE-- ++ ++--EXPECTF-- ++Warning: Header may not contain more than a single header, new line detected in %s on line %d ++foo ++--EXPECTHEADERS-- ++X-foo: e ++foo +Index: php5-5.3.5/ext/standard/tests/general_functions/bug60227_3.phpt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ php5-5.3.5/ext/standard/tests/general_functions/bug60227_3.phpt 2012-09-12 09:10:30.533070464 -0400 +@@ -0,0 +1,14 @@ ++--TEST-- ++Bug #60227 (header() cannot detect the multi-line header with CR), \0 before \n ++--FILE-- ++ ++--EXPECTF-- ++Warning: Header may not contain NUL bytes in %s on line %d ++foo ++--EXPECTHEADERS-- ++X-foo: e ++foo +Index: php5-5.3.5/ext/standard/tests/general_functions/bug60227_4.phpt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ php5-5.3.5/ext/standard/tests/general_functions/bug60227_4.phpt 2012-09-12 09:10:30.537070465 -0400 +@@ -0,0 +1,14 @@ ++--TEST-- ++Bug #60227 (header() cannot detect the multi-line header with CR), CRLF ++--FILE-- ++ ++--EXPECTF-- ++Warning: Header may not contain more than a single header, new line detected in %s on line %d ++foo ++--EXPECTHEADERS-- ++X-foo: e ++ foo +Index: php5-5.3.5/main/SAPI.c +=================================================================== +--- php5-5.3.5.orig/main/SAPI.c 2011-02-16 04:13:02.000000000 -0500 ++++ php5-5.3.5/main/SAPI.c 2012-09-12 09:10:30.573070465 -0400 +@@ -587,16 +587,26 @@ + return FAILURE; + } + } else { +- /* new line safety check */ +- char *s = header_line, *e = header_line + header_line_len, *p; +- while (s < e && (p = memchr(s, '\n', (e - s)))) { +- if (*(p + 1) == ' ' || *(p + 1) == '\t') { +- s = p + 1; +- continue; ++ /* new line/NUL character safety check */ ++ int i; ++ for (i = 0; i < header_line_len; i++) { ++ /* RFC 2616 allows new lines if followed by SP or HT */ ++ int illegal_break = ++ (header_line[i+1] != ' ' && header_line[i+1] != '\t') ++ && ( ++ header_line[i] == '\n' ++ || (header_line[i] == '\r' && header_line[i+1] != '\n')); ++ if (illegal_break) { ++ efree(header_line); ++ sapi_module.sapi_error(E_WARNING, "Header may not contain " ++ "more than a single header, new line detected"); ++ return FAILURE; ++ } ++ if (header_line[i] == '\0') { ++ efree(header_line); ++ sapi_module.sapi_error(E_WARNING, "Header may not contain NUL bytes"); ++ return FAILURE; + } +- efree(header_line); +- sapi_module.sapi_error(E_WARNING, "Header may not contain more than a single header, new line detected."); +- return FAILURE; + } + } + +Index: php5-5.3.5/ext/phar/phar_object.c +=================================================================== +--- php5-5.3.5.orig/ext/phar/phar_object.c 2012-09-12 09:10:15.965070091 -0400 ++++ php5-5.3.5/ext/phar/phar_object.c 2012-09-12 09:10:30.577070466 -0400 +@@ -427,7 +427,7 @@ + sapi_header_line ctr = {0}; + + ctr.response_code = 403; +- ctr.line_len = sizeof("HTTP/1.0 403 Access Denied"); ++ ctr.line_len = sizeof("HTTP/1.0 403 Access Denied")-1; + ctr.line = "HTTP/1.0 403 Access Denied"; + sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); + sapi_send_headers(TSRMLS_C); +@@ -452,7 +452,7 @@ + } + + ctr.response_code = 404; +- ctr.line_len = sizeof("HTTP/1.0 404 Not Found")+1; ++ ctr.line_len = sizeof("HTTP/1.0 404 Not Found")-1; + ctr.line = "HTTP/1.0 404 Not Found"; + sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); + sapi_send_headers(TSRMLS_C); +@@ -891,7 +891,7 @@ + char *tmp, sa; + sapi_header_line ctr = {0}; + ctr.response_code = 301; +- ctr.line_len = sizeof("HTTP/1.1 301 Moved Permanently")+1; ++ ctr.line_len = sizeof("HTTP/1.1 301 Moved Permanently")-1; + ctr.line = "HTTP/1.1 301 Moved Permanently"; + sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); + only in patch2: unchanged: --- php5-5.3.2.orig/debian/patches/CVE-2012-3450.patch +++ php5-5.3.2/debian/patches/CVE-2012-3450.patch @@ -0,0 +1,320 @@ +Description: fix denial of service via PDO extension crafted parameter +Origin: upstream, http://git.php.net/?p=php-src.git;a=commit;h=1b78aef426a8f413ddd70854eb3fd5fbc95ef675 +Origin: upstream, http://git.php.net/?p=php-src.git;a=commit;h=e946eaca0bc747615fabd0fedb8a92ea800ed158 +Origin: upstream, http://git.php.net/?p=php-src.git;a=commit;h=c06ec6bde43a114af3bd84e986827839de1b1e4b +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=683694 +Bug: https://bugs.php.net/bug.php?id=61755 + +Index: php5-5.3.6/ext/pdo_mysql/tests/bug_61755.phpt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ php5-5.3.6/ext/pdo_mysql/tests/bug_61755.phpt 2012-09-12 09:05:14.197062365 -0400 +@@ -0,0 +1,41 @@ ++--TEST-- ++Bug #61755 (A parsing bug in the prepared statements can lead to access violations) ++--SKIPIF-- ++ ++--FILE-- ++setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); ++ ++echo "NULL-Byte before first placeholder:\n"; ++$s = $db->prepare("SELECT \"a\0b\", ?"); ++$s->bindValue(1,"c"); ++$s->execute(); ++$r = $s->fetch(); ++echo "Length of item 0: ".strlen($r[0]).", Value of item 1: ".$r[1]."\n"; ++ ++echo "\nOpen comment:\n"; ++try { ++ $s = $db->prepare("SELECT /*"); ++ $s->execute(); ++} catch (Exception $e) { ++ echo "Error code: ".$e->getCode()."\n"; ++} ++ ++echo "\ndone!\n"; ++?> ++--EXPECTF-- ++NULL-Byte before first placeholder: ++Length of item 0: 3, Value of item 1: c ++ ++Open comment: ++Error code: 42000 ++ ++done! +Index: php5-5.3.6/ext/pdo/pdo_sql_parser.c +=================================================================== +--- php5-5.3.6.orig/ext/pdo/pdo_sql_parser.c 2011-03-17 03:56:01.000000000 -0400 ++++ php5-5.3.6/ext/pdo/pdo_sql_parser.c 2012-09-12 09:06:34.953064432 -0400 +@@ -1,4 +1,4 @@ +-/* Generated by re2c 0.13.6.dev on Thu Nov 13 14:47:06 2008 */ ++/* Generated by re2c 0.13.5 on Wed Sep 12 09:06:34 2012 */ + /* + +----------------------------------------------------------------------+ + | PHP Version 5 | +@@ -33,12 +33,12 @@ + + #define YYCTYPE unsigned char + #define YYCURSOR cursor +-#define YYLIMIT cursor ++#define YYLIMIT s->end + #define YYMARKER s->ptr +-#define YYFILL(n) ++#define YYFILL(n) { RET(PDO_PARSER_EOI); } + + typedef struct Scanner { +- char *ptr, *cur, *tok; ++ char *ptr, *cur, *tok, *end; + } Scanner; + + static int scan(Scanner *s) +@@ -46,7 +46,7 @@ + char *cursor = s->cur; + + s->tok = cursor; +- ++ + + + { +@@ -55,23 +55,26 @@ + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch (yych) { +- case 0x00: goto yy11; +- case '"': goto yy2; +- case '\'': goto yy4; +- case ':': goto yy5; +- case '?': goto yy6; +- default: goto yy8; ++ case 0x00: goto yy2; ++ case '"': goto yy3; ++ case '\'': goto yy5; ++ case ':': goto yy6; ++ case '?': goto yy7; ++ default: goto yy9; + } + yy2: +- yych = *(YYMARKER = ++YYCURSOR); +- if (yych >= 0x01) goto yy26; ++ YYCURSOR = YYMARKER; ++ goto yy4; + yy3: +- { SKIP_ONE(PDO_PARSER_TEXT); } +-yy4: + yych = *(YYMARKER = ++YYCURSOR); +- if (yych <= 0x00) goto yy3; +- goto yy20; ++ if (yych >= 0x01) goto yy24; ++yy4: ++ { SKIP_ONE(PDO_PARSER_TEXT); } + yy5: ++ yych = *(YYMARKER = ++YYCURSOR); ++ if (yych <= 0x00) goto yy4; ++ goto yy19; ++yy6: + yych = *++YYCURSOR; + switch (yych) { + case '0': +@@ -136,21 +139,21 @@ + case 'w': + case 'x': + case 'y': +- case 'z': goto yy16; ++ case 'z': goto yy15; + case ':': +- case '?': goto yy13; +- default: goto yy3; ++ case '?': goto yy12; ++ default: goto yy4; + } +-yy6: ++yy7: + ++YYCURSOR; + switch ((yych = *YYCURSOR)) { + case ':': +- case '?': goto yy13; +- default: goto yy7; ++ case '?': goto yy12; ++ default: goto yy8; + } +-yy7: +- { RET(PDO_PARSER_BIND_POS); } + yy8: ++ { RET(PDO_PARSER_BIND_POS); } ++yy9: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +@@ -159,26 +162,23 @@ + case '"': + case '\'': + case ':': +- case '?': goto yy10; +- default: goto yy8; ++ case '?': goto yy11; ++ default: goto yy9; + } +-yy10: +- { RET(PDO_PARSER_TEXT); } + yy11: +- ++YYCURSOR; +- { RET(PDO_PARSER_EOI); } +-yy13: ++ { RET(PDO_PARSER_TEXT); } ++yy12: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch (yych) { + case ':': +- case '?': goto yy13; +- default: goto yy15; ++ case '?': goto yy12; ++ default: goto yy14; + } +-yy15: ++yy14: + { RET(PDO_PARSER_TEXT); } +-yy16: ++yy15: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +@@ -245,52 +245,49 @@ + case 'w': + case 'x': + case 'y': +- case 'z': goto yy16; +- default: goto yy18; ++ case 'z': goto yy15; ++ default: goto yy17; + } +-yy18: ++yy17: + { RET(PDO_PARSER_BIND); } +-yy19: ++yy18: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +-yy20: ++yy19: + switch (yych) { +- case 0x00: goto yy21; +- case '\'': goto yy23; +- case '\\': goto yy22; +- default: goto yy19; ++ case 0x00: goto yy2; ++ case '\'': goto yy21; ++ case '\\': goto yy20; ++ default: goto yy18; + } +-yy21: +- YYCURSOR = YYMARKER; +- goto yy3; +-yy22: ++yy20: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +- if (yych <= 0x00) goto yy21; +- goto yy19; +-yy23: ++ if (yych <= 0x00) goto yy2; ++ goto yy18; ++yy21: + ++YYCURSOR; + { RET(PDO_PARSER_TEXT); } +-yy25: ++yy23: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +-yy26: ++yy24: + switch (yych) { +- case 0x00: goto yy21; +- case '"': goto yy28; +- case '\\': goto yy27; +- default: goto yy25; ++ case 0x00: goto yy2; ++ case '"': goto yy26; ++ case '\\': goto yy25; ++ default: goto yy23; + } +-yy27: ++yy25: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +- if (yych <= 0x00) goto yy21; +- goto yy25; +-yy28: ++ if (yych <= 0x00) goto yy2; ++ goto yy23; ++yy26: + ++YYCURSOR; + { RET(PDO_PARSER_TEXT); } + } +@@ -323,6 +320,7 @@ + + ptr = *outquery; + s.cur = inquery; ++ s.end = inquery + inquery_len + 1; + + /* phase 1: look for args */ + while((t = scan(&s)) != PDO_PARSER_EOI) { +Index: php5-5.3.6/ext/pdo/pdo_sql_parser.re +=================================================================== +--- php5-5.3.6.orig/ext/pdo/pdo_sql_parser.re 2010-12-31 21:19:59.000000000 -0500 ++++ php5-5.3.6/ext/pdo/pdo_sql_parser.re 2012-09-12 09:05:14.197062365 -0400 +@@ -32,12 +32,12 @@ + + #define YYCTYPE unsigned char + #define YYCURSOR cursor +-#define YYLIMIT cursor ++#define YYLIMIT s->end + #define YYMARKER s->ptr +-#define YYFILL(n) ++#define YYFILL(n) { RET(PDO_PARSER_EOI); } + + typedef struct Scanner { +- char *ptr, *cur, *tok; ++ char *ptr, *cur, *tok, *end; + } Scanner; + + static int scan(Scanner *s) +@@ -50,7 +50,6 @@ + QUESTION = [?]; + SPECIALS = [:?"']; + MULTICHAR = [:?]; +- EOF = [\000]; + ANYNOEOF = [\001-\377]; + */ + +@@ -62,7 +61,6 @@ + QUESTION { RET(PDO_PARSER_BIND_POS); } + SPECIALS { SKIP_ONE(PDO_PARSER_TEXT); } + (ANYNOEOF\SPECIALS)+ { RET(PDO_PARSER_TEXT); } +- EOF { RET(PDO_PARSER_EOI); } + */ + } + +@@ -92,6 +90,7 @@ + + ptr = *outquery; + s.cur = inquery; ++ s.end = inquery + inquery_len + 1; + + /* phase 1: look for args */ + while((t = scan(&s)) != PDO_PARSER_EOI) { only in patch2: unchanged: --- php5-5.3.2.orig/debian/patches/CVE-2012-2688.patch +++ php5-5.3.2/debian/patches/CVE-2012-2688.patch @@ -0,0 +1,38 @@ +Description: fix denial of service and possible code execution via + _php_stream_scandir function +Origin: upstream, http://git.php.net/?p=php-src.git;a=commit;h=7d04e0fb2ec8be9b1c4b16a9f0b4958f853597f1 +Origin: upstream, http://git.php.net/?p=php-src.git;a=commit;h=fc74503792b1ee92e4b813690890f3ed38fa3ad5 +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=683274 +Bug-Ubuntu: https://launchpad.net/bugs/1028064 + +Index: php5-5.3.2/main/streams/streams.c +=================================================================== +--- php5-5.3.2.orig/main/streams/streams.c 2010-02-04 19:39:31.000000000 -0500 ++++ php5-5.3.2/main/streams/streams.c 2012-09-12 11:32:50.493289130 -0400 +@@ -2144,8 +2144,8 @@ + php_stream *stream; + php_stream_dirent sdp; + char **vector = NULL; +- int vector_size = 0; +- int nfiles = 0; ++ unsigned int vector_size = 0; ++ unsigned int nfiles = 0; + + if (!namelist) { + return FAILURE; +@@ -2161,9 +2161,14 @@ + if (vector_size == 0) { + vector_size = 10; + } else { ++ if(vector_size*2 < vector_size) { ++ /* overflow */ ++ efree(vector); ++ return FAILURE; ++ } + vector_size *= 2; + } +- vector = (char **) erealloc(vector, vector_size * sizeof(char *)); ++ vector = (char **) safe_erealloc(vector, vector_size, sizeof(char *), 0); + } + + vector[nfiles] = estrdup(sdp.d_name);