From 921b6813da3237a83e908998483f46ae3d8bacba Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 31 Oct 2022 17:20:23 +0100 Subject: [PATCH 1/3] Fix #81740: PDO::quote() may return unquoted string `sqlite3_snprintf()` expects its first parameter to be `int`; we need to avoid overflow. --- ext/pdo_sqlite/sqlite_driver.c | 3 +++ ext/pdo_sqlite/tests/bug81740.phpt | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 ext/pdo_sqlite/tests/bug81740.phpt diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index 4233ff10ff2..5a72a1eda23 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -232,6 +232,9 @@ static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t /* NB: doesn't handle binary strings... use prepared stmts for that */ static int sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype ) { + if (unquotedlen > (INT_MAX - 3) / 2) { + return 0; + } *quoted = safe_emalloc(2, unquotedlen, 3); sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted); *quotedlen = strlen(*quoted); diff --git a/ext/pdo_sqlite/tests/bug81740.phpt b/ext/pdo_sqlite/tests/bug81740.phpt new file mode 100644 index 00000000000..99fb07c3048 --- /dev/null +++ b/ext/pdo_sqlite/tests/bug81740.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #81740 (PDO::quote() may return unquoted string) +--SKIPIF-- + +--INI-- +memory_limit=-1 +--FILE-- +quote($string)); +?> +--EXPECT-- +bool(false) From 5f90134bb69a345c7edb5013e6461e84caa32dbc Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 18 Dec 2022 22:52:30 -0700 Subject: [PATCH 2/3] Make build work with newer OpenSSL --- ext/openssl/openssl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 45a7e794400..9827c758716 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -1325,7 +1325,9 @@ PHP_MINIT_FUNCTION(openssl) REGISTER_LONG_CONSTANT("OPENSSL_CMS_NOSIGS", CMS_NOSIGS, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_PADDING", RSA_PKCS1_PADDING, CONST_CS|CONST_PERSISTENT); +#ifdef RSA_SSLV23_PADDING REGISTER_LONG_CONSTANT("OPENSSL_SSLV23_PADDING", RSA_SSLV23_PADDING, CONST_CS|CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("OPENSSL_NO_PADDING", RSA_NO_PADDING, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_OAEP_PADDING", RSA_PKCS1_OAEP_PADDING, CONST_CS|CONST_PERSISTENT); From a6a80eefe0413c91acd922bc58590a4db7979af0 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 18 Dec 2022 23:20:29 -0700 Subject: [PATCH 3/3] Improve fix for bug #81740 --- ext/pdo/pdo_dbh.c | 10 ++++++++-- ext/pdo/pdo_sql_parser.re | 7 +++++++ ext/pdo_sqlite/sqlite_driver.c | 4 ++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 5d3efe12e55..4c8af0597a2 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1161,7 +1161,7 @@ PHP_METHOD(PDO, query) PHP_METHOD(PDO, quote) { pdo_dbh_t *dbh = Z_PDO_DBH_P(ZEND_THIS); - zend_string *str; + zend_string *str, *quoted; zend_long paramtype = PDO_PARAM_STR; ZEND_PARSE_PARAMETERS_START(1, 2) @@ -1177,8 +1177,14 @@ PHP_METHOD(PDO, quote) pdo_raise_impl_error(dbh, NULL, "IM001", "driver does not support quoting"); RETURN_FALSE; } + quoted = dbh->methods->quoter(dbh, str, paramtype); - RETURN_STR(dbh->methods->quoter(dbh, str, paramtype)); + if (quoted == NULL) { + PDO_HANDLE_DBH_ERR(); + RETURN_FALSE; + } + + RETURN_STR(quoted); } /* }}} */ diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index 4c207003797..6bb0837fb31 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -242,6 +242,13 @@ safe: if (buf) { zend_string_release_ex(buf, 0); } + if (plc->quoted == NULL) { + /* bork */ + ret = -1; + strncpy(stmt->error_code, stmt->dbh->error_code, 6); + goto clean_up; + } + } else { pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource"); ret = -1; diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index 15e06fc0302..6d5015e0ba6 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -227,8 +227,8 @@ static zend_string *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const zend_string static zend_string* sqlite_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype) { char *quoted; - if (unquotedlen > (INT_MAX - 3) / 2) { - return 0; + if (ZSTR_LEN(unquoted) > (INT_MAX - 3) / 2) { + return NULL; } quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3); /* TODO use %Q format? */