From f79c7742746907d676989cb7f97fb4f7cd26789f Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 20 Jan 2020 18:05:00 +0100 Subject: [PATCH 1/4] Fix #79091: heap use-after-free in session_create_id() If the `new_id` is released, we must not use it again. --- ext/session/session.c | 1 + ext/session/tests/bug79091.phpt | 67 +++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 ext/session/tests/bug79091.phpt diff --git a/ext/session/session.c b/ext/session/session.c index 65fb30697cb..f470067faf0 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -2198,6 +2198,7 @@ static PHP_FUNCTION(session_create_id) /* Detect collision and retry */ if (PS(mod)->s_validate_sid(&PS(mod_data), new_id) == FAILURE) { zend_string_release(new_id); + new_id = NULL; continue; } break; diff --git a/ext/session/tests/bug79091.phpt b/ext/session/tests/bug79091.phpt new file mode 100644 index 00000000000..1d14427159a --- /dev/null +++ b/ext/session/tests/bug79091.phpt @@ -0,0 +1,67 @@ +--TEST-- +Bug #79091 (heap use-after-free in session_create_id()) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) +bool(true) + +Warning: session_create_id(): Failed to create new ID in %s on line %d From 0f79b1bf301f455967676b5129240140c5c45b09 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 20 Jan 2020 21:33:17 -0800 Subject: [PATCH 2/4] Fix #79099: OOB read in php_strip_tags_ex --- ext/standard/string.c | 6 ++--- ext/standard/tests/file/bug79099.phpt | 32 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 ext/standard/tests/file/bug79099.phpt diff --git a/ext/standard/string.c b/ext/standard/string.c index da51cd0966f..fb44cc505d9 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4866,7 +4866,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, uint8_t *stateptr, const if (state == 4) { /* Inside */ break; - } else if (state == 2 && *(p-1) != '\\') { + } else if (state == 2 && p >= buf + 1 && *(p-1) != '\\') { if (lc == c) { lc = '\0'; } else if (lc != '\\') { @@ -4893,7 +4893,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, uint8_t *stateptr, const case '!': /* JavaScript & Other HTML scripting languages */ - if (state == 1 && *(p-1) == '<') { + if (state == 1 && p >= buf + 1 && *(p-1) == '<') { state = 3; lc = c; } else { @@ -4920,7 +4920,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, uint8_t *stateptr, const case '?': - if (state == 1 && *(p-1) == '<') { + if (state == 1 && p >= buf + 1 && *(p-1) == '<') { br=0; state=2; break; diff --git a/ext/standard/tests/file/bug79099.phpt b/ext/standard/tests/file/bug79099.phpt new file mode 100644 index 00000000000..7c842f4654f --- /dev/null +++ b/ext/standard/tests/file/bug79099.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #79099 (OOB read in php_strip_tags_ex) +--FILE-- + +--EXPECT-- +string(0) "" +string(0) "" +string(0) "" +string(0) "" +string(0) "" +string(0) "" From 2bcbc95f033c31b00595ed39f79c3a99b4ed0501 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 20 Jan 2020 21:42:44 -0800 Subject: [PATCH 3/4] Fix bug #79037 (global buffer-overflow in `mbfl_filt_conv_big5_wchar`) --- ext/mbstring/libmbfl/filters/mbfilter_big5.c | 17 ++++++++++++----- ext/mbstring/tests/bug79037.phpt | 10 ++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 ext/mbstring/tests/bug79037.phpt diff --git a/ext/mbstring/libmbfl/filters/mbfilter_big5.c b/ext/mbstring/libmbfl/filters/mbfilter_big5.c index f5ab8809ce8..5e1ca815da3 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_big5.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_big5.c @@ -138,6 +138,17 @@ static unsigned short cp950_pua_tbl[][4] = { {0xf70f,0xf848,0xc740,0xc8fe}, }; +static inline int is_in_cp950_pua(int c1, int c) { + if ((c1 >= 0xfa && c1 <= 0xfe) || (c1 >= 0x8e && c1 <= 0xa0) || + (c1 >= 0x81 && c1 <= 0x8d) || (c1 >= 0xc7 && c1 <= 0xc8)) { + return (c >=0x40 && c <= 0x7e) || (c >= 0xa1 && c <= 0xfe); + } + if (c1 == 0xc6) { + return c >= 0xa1 && c <= 0xfe; + } + return 0; +} + /* * Big5 => wchar */ @@ -186,11 +197,7 @@ mbfl_filt_conv_big5_wchar(int c, mbfl_convert_filter *filter) if (filter->from->no_encoding == mbfl_no_encoding_cp950) { /* PUA for CP950 */ - if (w <= 0 && - (((c1 >= 0xfa && c1 <= 0xfe) || (c1 >= 0x8e && c1 <= 0xa0) || - (c1 >= 0x81 && c1 <= 0x8d) ||(c1 >= 0xc7 && c1 <= 0xc8)) - && ((c > 0x39 && c < 0x7f) || (c > 0xa0 && c < 0xff))) || - ((c1 == 0xc6) && (c > 0xa0 && c < 0xff))) { + if (w <= 0 && is_in_cp950_pua(c1, c)) { c2 = c1 << 8 | c; for (k = 0; k < sizeof(cp950_pua_tbl)/(sizeof(unsigned short)*4); k++) { if (c2 >= cp950_pua_tbl[k][2] && c2 <= cp950_pua_tbl[k][3]) { diff --git a/ext/mbstring/tests/bug79037.phpt b/ext/mbstring/tests/bug79037.phpt new file mode 100644 index 00000000000..94ff01a4a1d --- /dev/null +++ b/ext/mbstring/tests/bug79037.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #79037: global buffer-overflow in `mbfl_filt_conv_big5_wchar` +--FILE-- + +--EXPECT-- +string(1) "?" From 5c90f8eb66cc8ad0e9377dcf46ad2252924dfb29 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 20 Jan 2020 22:12:32 -0800 Subject: [PATCH 4/4] Update NEWS --- NEWS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NEWS b/NEWS index cb4a4ac5949..2d9703be309 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,15 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2019, PHP 7.2.27 +- Mbstring: + . Fixed bug #79037 (global buffer-overflow in `mbfl_filt_conv_big5_wchar`). + (CVE-2020-7060) (Nikita) + +- Session: + . Fixed bug #79091 (heap use-after-free in session_create_id()). (cmb, Nikita) + +- Standard: + . Fixed bug #79099 (OOB read in php_strip_tags_ex). (CVE-2020-7059). (cmb) 18 Dec 2019, PHP 7.2.26