From 8ff180f0298116f0535cb02bd5b978dd72a1dd30 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 28 Jun 2021 14:54:19 +0200 Subject: Fix #81122 SSRF bypass in FILTER_VALIDATE_URL CVE-2021-21705 Fix #76448 Stack buffer overflow in firebird_info_cb Fix #76449 SIGSEGV in firebird_handle_doer Fix #76450 SIGSEGV in firebird_stmt_execute Fix #76452 Crash while parsing blob data in firebird_fetch_blob CVE-2021-21704 --- php-bug76450.patch | 436 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 436 insertions(+) create mode 100644 php-bug76450.patch (limited to 'php-bug76450.patch') diff --git a/php-bug76450.patch b/php-bug76450.patch new file mode 100644 index 0000000..1fa0ddd --- /dev/null +++ b/php-bug76450.patch @@ -0,0 +1,436 @@ +From 24dbc542d1ef501479dcd365f1bc53a859981dc0 Mon Sep 17 00:00:00 2001 +From: sim1984 +Date: Mon, 25 Jun 2018 21:35:51 +0300 +Subject: [PATCH 1/9] Fix bug #76488 Memory leak when fetching a BLOB field + +Add a phpt test + +(cherry picked from commit 3847a6fcb63c362548e9434b195232f2dcf7a6c7) +(cherry picked from commit b671a8dd887ae7f661f6233e734179e8bca3daf6) +--- + ext/pdo_firebird/firebird_statement.c | 4 ++-- + ext/pdo_firebird/tests/bug_76488.phpt | 32 +++++++++++++++++++++++++++ + 2 files changed, 34 insertions(+), 2 deletions(-) + create mode 100644 ext/pdo_firebird/tests/bug_76488.phpt + +diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c +index d1f1012637..8b8f82252a 100644 +--- a/ext/pdo_firebird/firebird_statement.c ++++ b/ext/pdo_firebird/firebird_statement.c +@@ -267,8 +267,8 @@ static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ * + unsigned short seg_len; + ISC_STATUS stat; + +- *ptr = S->fetch_buf[colno] = erealloc(*ptr, *len+1); +- ++ *ptr = S->fetch_buf[colno] = erealloc(S->fetch_buf[colno], *len+1); ++ + for (cur_len = stat = 0; (!stat || stat == isc_segment) && cur_len < *len; cur_len += seg_len) { + + unsigned short chunk_size = (*len-cur_len) > USHRT_MAX ? USHRT_MAX +diff --git a/ext/pdo_firebird/tests/bug_76488.phpt b/ext/pdo_firebird/tests/bug_76488.phpt +new file mode 100644 +index 0000000000..dba6734c28 +--- /dev/null ++++ b/ext/pdo_firebird/tests/bug_76488.phpt +@@ -0,0 +1,32 @@ ++--TEST-- ++PDO_Firebird: Bug #76488 Memory leak when fetching a BLOB field ++--SKIPIF-- ++ ++--FILE-- ++prepare($sql); ++ $sth->execute(); ++ $rows = $sth->fetchAll(); ++ unset($rows); ++ unset($sth); ++ } ++ unset($dbh); ++ echo "OK"; ++?> ++--EXPECT-- ++OK +\ No newline at end of file +-- +2.31.1 + +From 7024ff99e8659d9e2d80299ea35f9a78292fa064 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Wed, 5 May 2021 12:42:17 +0200 +Subject: [PATCH 2/9] Fix #76452: Crash while parsing blob data in + firebird_fetch_blob + +We need to prevent integer overflow when calling `erealloc()` with +`len+1`. + +(cherry picked from commit 286162e9b03071c4308e7e92597bca4239f49d89) +--- + ext/pdo_firebird/firebird_statement.c | 5 +++++ + ext/pdo_firebird/tests/bug_76452.data | Bin 0 -> 856 bytes + ext/pdo_firebird/tests/bug_76452.phpt | 31 ++++++++++++++++++++++++++ + 3 files changed, 36 insertions(+) + create mode 100644 ext/pdo_firebird/tests/bug_76452.data + create mode 100644 ext/pdo_firebird/tests/bug_76452.phpt + +diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c +index 8b8f82252a..cb7e4bd83a 100644 +--- a/ext/pdo_firebird/firebird_statement.c ++++ b/ext/pdo_firebird/firebird_statement.c +@@ -267,6 +267,11 @@ static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ * + unsigned short seg_len; + ISC_STATUS stat; + ++ /* prevent overflow */ ++ if (*len == ZEND_ULONG_MAX) { ++ result = 0; ++ goto fetch_blob_end; ++ } + *ptr = S->fetch_buf[colno] = erealloc(S->fetch_buf[colno], *len+1); + + for (cur_len = stat = 0; (!stat || stat == isc_segment) && cur_len < *len; cur_len += seg_len) { + +From b0fed22401d1237a26ec9ac951ca4c7abf512883 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Fri, 30 Apr 2021 14:10:50 +0200 +Subject: [PATCH 3/9] Fix #76450: SIGSEGV in firebird_stmt_execute + +We need to verify that the `result_size` is not larger than our buffer, +and also should make sure that the `len` which is passed to +`isc_vax_integer()` has a permissible value; otherwise we bail out. + +(cherry picked from commit bcbf8aa0c96d8d9e81ec3428232485555fae0b37) +--- + ext/pdo_firebird/firebird_statement.c | 9 +++++++- + ext/pdo_firebird/tests/bug_76450.data | Bin 0 -> 464 bytes + ext/pdo_firebird/tests/bug_76450.phpt | 29 ++++++++++++++++++++++++++ + 3 files changed, 37 insertions(+), 1 deletion(-) + create mode 100644 ext/pdo_firebird/tests/bug_76450.data + create mode 100644 ext/pdo_firebird/tests/bug_76450.phpt + +diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c +index cb7e4bd83a..a87bcc1d40 100644 +--- a/ext/pdo_firebird/firebird_statement.c ++++ b/ext/pdo_firebird/firebird_statement.c +@@ -120,8 +120,14 @@ static int firebird_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */ + } + if (result[0] == isc_info_sql_records) { + unsigned i = 3, result_size = isc_vax_integer(&result[1], 2); ++ if (result_size > sizeof(result)) { ++ goto error; ++ } + while (result[i] != isc_info_end && i < result_size) { + short len = (short) isc_vax_integer(&result[i + 1], 2); ++ if (len != 1 && len != 2 && len != 4) { ++ goto error; ++ } + if (result[i] != isc_info_req_select_count) { + affected_rows += isc_vax_integer(&result[i + 3], len); + } +@@ -145,7 +151,8 @@ static int firebird_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */ + return 1; + } while (0); + +- RECORD_ERROR(stmt); ++error: ++ RECORD_ERROR(stmt); + + return 0; + } + +From d5572d9dbcc90366e043521b43e7553b75d20662 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Fri, 30 Apr 2021 13:53:21 +0200 +Subject: [PATCH 4/9] Fix #76449: SIGSEGV in firebird_handle_doer + +We need to verify that the `result_size` is not larger than our buffer, +and also should make sure that the `len` which is passed to +`isc_vax_integer()` has a permissible value; otherwise we bail out. + +(cherry picked from commit 08da7c73726f7b86b67d6f0ff87c73c585a7834a) +--- + ext/pdo_firebird/firebird_driver.c | 9 +++++++++ + ext/pdo_firebird/tests/bug_76449.data | Bin 0 -> 464 bytes + ext/pdo_firebird/tests/bug_76449.phpt | 23 +++++++++++++++++++++++ + 3 files changed, 32 insertions(+) + create mode 100644 ext/pdo_firebird/tests/bug_76449.data + create mode 100644 ext/pdo_firebird/tests/bug_76449.phpt + +diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c +index a3f34d554f..fef58cb3b4 100644 +--- a/ext/pdo_firebird/firebird_driver.c ++++ b/ext/pdo_firebird/firebird_driver.c +@@ -253,8 +253,17 @@ static long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len T + if (result[0] == isc_info_sql_records) { + unsigned i = 3, result_size = isc_vax_integer(&result[1],2); + ++ if (result_size > sizeof(result)) { ++ ret = -1; ++ goto free_statement; ++ } + while (result[i] != isc_info_end && i < result_size) { + short len = (short)isc_vax_integer(&result[i+1],2); ++ /* bail out on bad len */ ++ if (len != 1 && len != 2 && len != 4) { ++ ret = -1; ++ goto free_statement; ++ } + if (result[i] != isc_info_req_select_count) { + ret += isc_vax_integer(&result[i+3],len); + } + +From 2e174eac00ecffc4dd4884e801d15d22f80ffa98 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Thu, 29 Apr 2021 15:26:22 +0200 +Subject: [PATCH 5/9] Fix #76448: Stack buffer overflow in firebird_info_cb + +We ensure not to overflow the stack allocated buffer by using `strlcat`. + +(cherry picked from commit 67afa32541ebc4abbf633cb1e7e879b2fbb616ad) +--- + ext/pdo_firebird/firebird_driver.c | 10 ++++++---- + ext/pdo_firebird/tests/bug_76448.data | Bin 0 -> 749 bytes + ext/pdo_firebird/tests/bug_76448.phpt | 23 +++++++++++++++++++++++ + 3 files changed, 29 insertions(+), 4 deletions(-) + create mode 100644 ext/pdo_firebird/tests/bug_76448.data + create mode 100644 ext/pdo_firebird/tests/bug_76448.phpt + +diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c +index fef58cb3b4..5f3d3cdb02 100644 +--- a/ext/pdo_firebird/firebird_driver.c ++++ b/ext/pdo_firebird/firebird_driver.c +@@ -540,14 +540,16 @@ static int firebird_handle_set_attribute(pdo_dbh_t *dbh, long attr, zval *val TS + } + /* }}} */ + ++#define INFO_BUF_LEN 512 ++ + /* callback to used to report database server info */ + static void firebird_info_cb(void *arg, char const *s) /* {{{ */ + { + if (arg) { + if (*(char*)arg) { /* second call */ +- strcat(arg, " "); ++ strlcat(arg, " ", INFO_BUF_LEN); + } +- strcat(arg, s); ++ strlcat(arg, s, INFO_BUF_LEN); + } + } + /* }}} */ +@@ -558,8 +560,8 @@ static int firebird_handle_get_attribute(pdo_dbh_t *dbh, long attr, zval *val TS + pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; + + switch (attr) { +- char tmp[512]; +- ++ char tmp[INFO_BUF_LEN]; ++ + case PDO_ATTR_AUTOCOMMIT: + ZVAL_LONG(val,dbh->auto_commit); + return 1; + +From bd5936bc8ce2e3c8497b9083f5530e83f5a19616 Mon Sep 17 00:00:00 2001 +From: Dorin Marcoci +Date: Sat, 24 Dec 2016 13:57:03 +0200 +Subject: [PATCH 7/9] Fixes #65689. PDO_Firebrid / exec() does not free + allocated statement. + +(cherry picked from commit e926bf65076cb5c8da6bf8f32635f696de5ff9aa) +--- + ext/pdo_firebird/firebird_driver.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c +index 5f3d3cdb02..589312ac3a 100644 +--- a/ext/pdo_firebird/firebird_driver.c ++++ b/ext/pdo_firebird/firebird_driver.c +@@ -240,14 +240,16 @@ static long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len T + /* execute the statement */ + if (isc_dsql_execute2(H->isc_status, &H->tr, &stmt, PDO_FB_SQLDA_VERSION, &in_sqlda, &out_sqlda)) { + RECORD_ERROR(dbh); +- return -1; ++ ret = -1; ++ goto free_statement; + } + + /* find out how many rows were affected */ + if (isc_dsql_sql_info(H->isc_status, &stmt, sizeof(info_count), const_cast(info_count), + sizeof(result), result)) { + RECORD_ERROR(dbh); +- return -1; ++ ret = -1; ++ goto free_statement; + } + + if (result[0] == isc_info_sql_records) { +@@ -276,6 +278,12 @@ static long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len T + RECORD_ERROR(dbh); + } + ++free_statement: ++ ++ if (isc_dsql_free_statement(H->isc_status, &stmt, DSQL_drop)) { ++ RECORD_ERROR(dbh); ++ } ++ + return ret; + } + /* }}} */ +-- +2.31.1 + +From 79aadb61954cb38b7b97897482e0a3a08cd90874 Mon Sep 17 00:00:00 2001 +From: Anatol Belski +Date: Mon, 6 Jun 2016 13:30:17 +0200 +Subject: [PATCH 8/9] fix ibase handle initialization, mostly compiler warnings + +(cherry picked from commit 3e6c02b91a62e3fd640dfa199f8e4178a6680821) +--- + ext/pdo_firebird/firebird_driver.c | 4 ++-- + ext/pdo_firebird/firebird_statement.c | 4 ++-- + ext/pdo_firebird/php_pdo_firebird_int.h | 6 ++++++ + 3 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c +index 589312ac3a..84de8affd6 100644 +--- a/ext/pdo_firebird/firebird_driver.c ++++ b/ext/pdo_firebird/firebird_driver.c +@@ -140,7 +140,7 @@ static int firebird_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_le + HashTable *np; + + do { +- isc_stmt_handle s = NULL; ++ isc_stmt_handle s = PDO_FIREBIRD_HANDLE_INITIALIZER; + XSQLDA num_sqlda; + static char const info[] = { isc_info_sql_stmt_type }; + char result[8]; +@@ -221,7 +221,7 @@ static int firebird_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_le + static long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC) /* {{{ */ + { + pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; +- isc_stmt_handle stmt = NULL; ++ isc_stmt_handle stmt = PDO_FIREBIRD_HANDLE_INITIALIZER; + static char const info_count[] = { isc_info_sql_records }; + char result[64]; + int ret = 0; +diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c +index a87bcc1d40..dc64c19687 100644 +--- a/ext/pdo_firebird/firebird_statement.c ++++ b/ext/pdo_firebird/firebird_statement.c +@@ -230,7 +230,7 @@ static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ * + { + pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data; + pdo_firebird_db_handle *H = S->H; +- isc_blob_handle blobh = NULL; ++ isc_blob_handle blobh = PDO_FIREBIRD_HANDLE_INITIALIZER; + char const bl_item = isc_info_blob_total_length; + char bl_info[20]; + unsigned short i; +@@ -424,7 +424,7 @@ static int firebird_bind_blob(pdo_stmt_t *stmt, ISC_QUAD *blob_id, zval *param T + { + pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data; + pdo_firebird_db_handle *H = S->H; +- isc_blob_handle h = NULL; ++ isc_blob_handle h = PDO_FIREBIRD_HANDLE_INITIALIZER; + unsigned long put_cnt = 0, rem_cnt; + unsigned short chunk_size; + int result = 1; +diff --git a/ext/pdo_firebird/php_pdo_firebird_int.h b/ext/pdo_firebird/php_pdo_firebird_int.h +index 796f3837c8..09cd485121 100644 +--- a/ext/pdo_firebird/php_pdo_firebird_int.h ++++ b/ext/pdo_firebird/php_pdo_firebird_int.h +@@ -61,6 +61,12 @@ typedef void (*info_func_t)(char*); + #define min(a,b) ((a)<(b)?(a):(b)) + #endif + ++#if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(_WIN64) ++# define PDO_FIREBIRD_HANDLE_INITIALIZER 0U ++#else ++# define PDO_FIREBIRD_HANDLE_INITIALIZER NULL ++#endif ++ + typedef struct { + + /* the result of the last API call */ +-- +2.31.1 + +From 82b3778dcb7ad665e6fd299e0c811bb94195bf49 Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Mon, 28 Jun 2021 14:31:02 +0200 +Subject: [PATCH 9/9] adapt for 5.6 without ZEND_ULONG_MAX + +--- + ext/pdo_firebird/firebird_statement.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c +index dc64c19687..ea3c704fbb 100644 +--- a/ext/pdo_firebird/firebird_statement.c ++++ b/ext/pdo_firebird/firebird_statement.c +@@ -275,7 +275,7 @@ static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ * + ISC_STATUS stat; + + /* prevent overflow */ +- if (*len == ZEND_ULONG_MAX) { ++ if (*len == (LONG_MAX * 2UL +1UL)) { + result = 0; + goto fetch_blob_end; + } +-- +2.31.1 + +From 7ce2b28871fcf07a9f3ac0947bb6c4973b28224f Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sun, 20 Jun 2021 22:20:38 -0700 +Subject: [PATCH 6/9] Update NEWS + +(cherry picked from commit c68a687566591e2268f35d124a90c7d556ce968b) +(cherry picked from commit 7598733c51af30611aa64e456c9a777069d2efb9) +--- + NEWS | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/NEWS b/NEWS +index 659bab855a..03d8a03ec1 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,6 +1,19 @@ + PHP NEWS + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + ++Backported from 7.3.29 ++ ++- Core: ++ . Fixed #81122: SSRF bypass in FILTER_VALIDATE_URL. (CVE-2021-21705) (cmb) ++ ++- PDO_Firebird: ++ . Fixed #76448: Stack buffer overflow in firebird_info_cb. (CVE-2021-21704) ++ (cmb) ++ . Fixed #76449: SIGSEGV in firebird_handle_doer. (CVE-2021-21704) (cmb) ++ . Fixed #76450: SIGSEGV in firebird_stmt_execute. (CVE-2021-21704) (cmb) ++ . Fixed #76452: Crash while parsing blob data in firebird_fetch_blob. ++ (CVE-2021-21704) (cmb) ++ + Backported from 7.3.28 + + - Imap: +-- +2.31.1 + -- cgit