public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/php-extras] epel9: Fix SQL injection via NUL bytes in quoted strings
@ 2026-06-03 9:44 Remi Collet
0 siblings, 0 replies; only message in thread
From: Remi Collet @ 2026-06-03 9:44 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/php-extras
Branch : epel9
Commit : fe822628da71c5bb9f76b7d34b18b755d48178b9
Author : Remi Collet <remi@fedoraproject.org>
Date : 2026-06-03T11:44:51+02:00
Stats : +279/-1 in 2 file(s)
URL : https://src.fedoraproject.org/rpms/php-extras/c/fe822628da71c5bb9f76b7d34b18b755d48178b9?branch=epel9
Log:
Fix SQL injection via NUL bytes in quoted strings
CVE-2025-14179
---
diff --git a/php-cve-2025-14179.patch b/php-cve-2025-14179.patch
new file mode 100644
index 0000000..d51aeb4
--- /dev/null
+++ b/php-cve-2025-14179.patch
@@ -0,0 +1,272 @@
+From abf5a10618537332f63194f2cf72b019c592029c Mon Sep 17 00:00:00 2001
+From: Saki Takamachi <saki@sakiot.com>
+Date: Sun, 3 May 2026 19:56:30 +0200
+Subject: [PATCH] GHSA-w476-322c-wpvm: [pdo_firebird] Fix SQL injection via NUL
+ bytes in quoted strings
+
+Fixes GHSA-w476-322c-wpvm
+Fixes CVE-2025-14179
+
+(cherry picked from commit 3f40b65323dd1b85e9bab6878237d3867e449d5c)
+(cherry picked from commit 4b0dd469bbba7bf5f25f1a4f694aeb15c3515be4)
+---
+ ext/pdo_firebird/firebird_driver.c | 68 ++++++++++++-------
+ .../tests/ghsa-w476-322c-wpvm.phpt | 44 ++++++++++++
+ 2 files changed, 88 insertions(+), 24 deletions(-)
+ create mode 100644 ext/pdo_firebird/tests/ghsa-w476-322c-wpvm.phpt
+
+diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c
+index fb69797850..06a33651d7 100644
+--- a/ext/pdo_firebird/firebird_driver.c
++++ b/ext/pdo_firebird/firebird_driver.c
+@@ -290,7 +290,7 @@ static FbTokenType getToken(const char** begin, const char* end)
+ return ret;
+ }
+
+-int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_params)
++int preprocess(const char* sql, int sql_len, char* sql_out, size_t* sql_out_len, HashTable* named_params)
+ {
+ zend_bool passAsIs = 1, execBlock = 0;
+ zend_long pindex = -1;
+@@ -321,7 +321,7 @@ int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_par
+ if (l > 252) {
+ return 0;
+ }
+- strncpy(ident, i, l);
++ memcpy(ident, i, l);
+ ident[l] = '\0';
+ if (!strcasecmp(ident, "EXECUTE"))
+ {
+@@ -346,7 +346,7 @@ int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_par
+ if (l > 252) {
+ return 0;
+ }
+- strncpy(ident2, i2, l);
++ memcpy(ident2, i2, l);
+ ident2[l] = '\0';
+ execBlock = !strcasecmp(ident2, "BLOCK");
+ passAsIs = 0;
+@@ -362,11 +362,15 @@ int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_par
+
+ if (passAsIs)
+ {
+- strcpy(sql_out, sql);
++ memcpy(sql_out, sql, sql_len);
++ sql_out[sql_len] = '\0';
++ *sql_out_len = sql_len;
+ return 1;
+ }
+
+- strncat(sql_out, start, p - start);
++ char *sql_out_p = sql_out;
++ memcpy(sql_out_p, start, p - start);
++ sql_out_p += p - start;
+
+ while (p < end)
+ {
+@@ -374,10 +378,12 @@ int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_par
+ tok = getToken(&p, end);
+ switch (tok)
+ {
+- case ttParamMark:
+- tok = getToken(&p, end);
++ case ttParamMark: {
++ const char* p_peek = p;
++ tok = getToken(&p_peek, end);
+ if (tok == ttIdent /*|| tok == ttString*/)
+ {
++ p = p_peek;
+ ++pindex;
+ l = p - start;
+ /* check the length of the identifier */
+@@ -386,7 +392,7 @@ int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_par
+ if (l > 253) {
+ return 0;
+ }
+- strncpy(pname, start, l);
++ memcpy(pname, start, l);
+ pname[l] = '\0';
+
+ if (named_params) {
+@@ -395,7 +401,7 @@ int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_par
+ zend_hash_str_update(named_params, pname, l, &tmp);
+ }
+
+- strcat(sql_out, "?");
++ *sql_out_p++ = '?';
+ }
+ else
+ {
+@@ -405,10 +411,11 @@ int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_par
+ return 0;
+ }
+ ++pindex;
+- strncat(sql_out, start, p - start);
++ memcpy(sql_out_p, start, p - start);
++ sql_out_p += p - start;
+ }
+ break;
+-
++ }
+ case ttIdent:
+ if (execBlock)
+ {
+@@ -420,11 +427,14 @@ int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_par
+ if (l > 252) {
+ return 0;
+ }
+- strncpy(ident, start, l);
++ memcpy(ident, start, l);
+ ident[l] = '\0';
+ if (!strcasecmp(ident, "AS"))
+ {
+- strncat(sql_out, start, end - start);
++ memcpy(sql_out_p, start, end - start);
++ sql_out_p += end - start;
++ *sql_out_p = '\0';
++ *sql_out_len = sql_out_p - sql_out;
+ return 1;
+ }
+ }
+@@ -433,7 +443,8 @@ int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_par
+ case ttComment:
+ case ttString:
+ case ttOther:
+- strncat(sql_out, start, p - start);
++ memcpy(sql_out_p, start, p - start);
++ sql_out_p += p - start;
+ break;
+
+ case ttBrokenComment:
+@@ -451,6 +462,8 @@ int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_par
+ break;
+ }
+ }
++ *sql_out_p = '\0';
++ *sql_out_len = sql_out_p - sql_out;
+ return 1;
+ }
+
+@@ -664,7 +677,7 @@ static int firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t u
+ char **quoted, size_t *quotedlen, enum pdo_param_type paramtype)
+ {
+ size_t qcount = 0;
+- char const *co, *l, *r;
++ char const *co, *l;
+ char *c;
+
+ if (!unquotedlen) {
+@@ -674,9 +687,15 @@ static int firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t u
+ return 1;
+ }
+
++ const char * const end = unquoted + unquotedlen;
++
+ /* Firebird only requires single quotes to be doubled if string lengths are used */
+ /* count the number of ' characters */
+- for (co = unquoted; (co = strchr(co,'\'')); qcount++, co++);
++ for (co = unquoted; co < end; co++) {
++ if (*co == '\'') {
++ qcount++;
++ }
++ }
+
+ if (UNEXPECTED(unquotedlen + 2 > ZSTR_MAX_LEN - qcount)) {
+ return 0;
+@@ -687,15 +706,15 @@ static int firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t u
+ *c++ = '\'';
+
+ /* foreach (chunk that ends in a quote) */
+- for (l = unquoted; (r = strchr(l,'\'')); l = r+1) {
+- strncpy(c, l, r-l+1);
+- c += (r-l+1);
+- /* add the second quote */
+- *c++ = '\'';
++ for (l = unquoted; l < end; l++) {
++ *c++ = *l;
++ if (*l == '\'') {
++ /* add the second quote */
++ *c++ = '\'';
++ }
+ }
+
+ /* copy the remainder */
+- strncpy(c, l, *quotedlen-(c-*quoted)-1);
+ (*quoted)[*quotedlen-1] = '\'';
+ (*quoted)[*quotedlen] = '\0';
+
+@@ -788,6 +807,7 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const char *sql, size_t s
+ {
+ pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
+ char *new_sql;
++ size_t new_sql_len;
+
+ /* Firebird allows SQL statements up to 64k, so bail if it doesn't fit */
+ if (sql_len > 65536) {
+@@ -815,14 +835,14 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const char *sql, size_t s
+ we need to replace :foo by ?, and store the name we just replaced */
+ new_sql = emalloc(sql_len+1);
+ new_sql[0] = '\0';
+- if (!preprocess(sql, sql_len, new_sql, named_params)) {
++ if (!preprocess(sql, sql_len, new_sql, &new_sql_len, named_params)) {
+ strcpy(dbh->error_code, "07000");
+ efree(new_sql);
+ return 0;
+ }
+
+ /* prepare the statement */
+- if (isc_dsql_prepare(H->isc_status, &H->tr, s, 0, new_sql, H->sql_dialect, out_sqlda)) {
++ if (isc_dsql_prepare(H->isc_status, &H->tr, s, new_sql_len, new_sql, H->sql_dialect, out_sqlda)) {
+ RECORD_ERROR(dbh);
+ efree(new_sql);
+ return 0;
+diff --git a/ext/pdo_firebird/tests/ghsa-w476-322c-wpvm.phpt b/ext/pdo_firebird/tests/ghsa-w476-322c-wpvm.phpt
+new file mode 100644
+index 0000000000..41c1125e9b
+--- /dev/null
++++ b/ext/pdo_firebird/tests/ghsa-w476-322c-wpvm.phpt
+@@ -0,0 +1,44 @@
++--TEST--
++GHSA-w476-322c-wpvm: SQL injection in pdo_firebird via NUL bytes in quoted strings
++--EXTENSIONS--
++pdo_firebird
++--SKIPIF--
++<?php require('skipif.inc'); ?>
++--XLEAK--
++A bug in firebird causes a memory leak when calling `isc_attach_database()`.
++See https://github.com/FirebirdSQL/firebird/issues/7849
++--FILE--
++<?php
++
++require("testdb.inc");
++
++$dbh->exec('CREATE TABLE ghsa_w476_322c_wpvm (name VARCHAR(255))');
++
++$param = $dbh->quote("\0");
++$param2 = $dbh->quote('or 1=1--');
++var_export($param);
++echo("\n");
++
++echo "prepare: ";
++$stmt = $dbh->prepare("SELECT * FROM ghsa_w476_322c_wpvm WHERE name = {$param} AND name = {$param2}");
++$stmt->execute();
++echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)) . "\n";
++
++echo "query: ";
++$stmt = $dbh->query("SELECT * FROM ghsa_w476_322c_wpvm WHERE name = {$param} AND name = {$param2}");
++echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)) . "\n";
++
++echo "exec: ";
++$affectedRows = $dbh->exec("UPDATE ghsa_w476_322c_wpvm SET name = 'updated' WHERE name = {$param} AND name = {$param2}");
++echo $affectedRows . "\n";
++?>
++--CLEAN--
++<?php
++require 'testdb.inc';
++$dbh->exec("DROP TABLE ghsa_w476_322c_wpvm");
++?>
++--EXPECT--
++'\'' . "\0" . '\''
++prepare: []
++query: []
++exec: 0
diff --git a/php-extras.spec b/php-extras.spec
index 06a1988..720aa28 100644
--- a/php-extras.spec
+++ b/php-extras.spec
@@ -13,13 +13,14 @@
Name: php-extras
Summary: Additional PHP extensions from the standard PHP distribution
Version: 8.0.30
-Release: 2%{?dist}
+Release: 3%{?dist}
License: PHP
URL: https://www.php.net/
Source0: https://www.php.net/distributions/php-%{version}.tar.xz
# Security patches
Patch100: php-cve-2024-11236.patch
+Patch101: php-cve-2025-14179.patch
BuildRequires: (php-devel >= 8.0 with php-devel < 8.1)
BuildRequires: php-pdo
@@ -140,6 +141,7 @@ low-level PHP extension for the libsodium cryptographic library.
%setup -q -n php-%{version}
%patch -P100 -p1 -b .cve11236
+%patch -P101 -p1 -b .cve14179
%build
@@ -310,6 +312,10 @@ done
%endif
%changelog
+* Wed Jun 3 2026 Remi Collet <rcollet@redhat.com> - 8.0.30-3
+- Fix SQL injection via NUL bytes in quoted strings
+ CVE-2025-14179
+
* Fri Nov 29 2024 Remi Collet <rcollet@redhat.com> - 8.0.30-2
- Fix Integer overflow in the dblib/firebird quoter causing OOB writes
CVE-2024-11236
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-06-03 9:44 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-03 9:44 [rpms/php-extras] epel9: Fix SQL injection via NUL bytes in quoted strings Remi Collet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox