Fix heap overflow when preparsing SQL statements with excessive placeholders (CVE-2026-14739)
Resolves: RHEL-193298
This commit is contained in:
parent
9a1f6bd5d2
commit
b0d0d60e8a
128
DBI-1.643-Fix-CVE-2026-14739.patch
Normal file
128
DBI-1.643-Fix-CVE-2026-14739.patch
Normal file
@ -0,0 +1,128 @@
|
||||
From 877297ada6974a4f35db2cb30ee3f32a8c50bca3 Mon Sep 17 00:00:00 2001
|
||||
From: "H.Merijn Brand - Tux" <linux@tux.freedom.nl>
|
||||
Date: Sat, 4 Jul 2026 11:38:24 +0200
|
||||
Subject: [PATCH] Set a hard limit of 99999 on '?' placeholders
|
||||
(CVE-2026-14739)
|
||||
|
||||
---
|
||||
DBI.pm | 6 ++++--
|
||||
DBI.xs | 53 +++++++++++++++++++++++++++++++++--------------------
|
||||
2 files changed, 37 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/DBI.pm b/DBI.pm
|
||||
index d62a32d..b988e40 100644
|
||||
--- a/DBI.pm
|
||||
+++ b/DBI.pm
|
||||
@@ -7123,7 +7123,8 @@ a ref to an empty hash because they can't pre-determine the names.
|
||||
It is possible that the keys in the hash returned by C<ParamValues>
|
||||
are not exactly the same as those implied by the prepared statement.
|
||||
For example, DBD::Oracle translates 'C<?>' placeholders into 'C<:pN>'
|
||||
-where N is a sequence number starting at 1.
|
||||
+where N is a sequence number starting at C<1> with a hard limit of
|
||||
+C<99999>.
|
||||
|
||||
* Values:
|
||||
|
||||
@@ -7225,7 +7226,8 @@ integer.
|
||||
It is also possible that the keys in the hash returned by
|
||||
C<ParamArrays> are not exactly the same as those implied by the
|
||||
prepared statement. For example, DBD::Oracle translates 'C<?>'
|
||||
-placeholders into 'C<:pN>' where N is a sequence number starting at 1.
|
||||
+placeholders into 'C<:pN>' where N is a sequence number starting at
|
||||
+C<1> with a hard limit of C<99999>.
|
||||
|
||||
=head3 C<RowsInCache>
|
||||
|
||||
diff --git a/DBI.xs b/DBI.xs
|
||||
index 8858e21..23ad34a 100644
|
||||
--- a/DBI.xs
|
||||
+++ b/DBI.xs
|
||||
@@ -4201,7 +4201,14 @@ preparse(SV *dbh, const char *statement, IV ps_return, IV ps_accept, void *foo)
|
||||
}
|
||||
|
||||
/* XXX this allocation strategy won't work when we get to more advanced stuff */
|
||||
- new_stmt_sv = newSV(strlen(statement) * 6 + 16);
|
||||
+ /* The 7 is for length increase from '?' (length 1) to :p99999 (length 7)
|
||||
+ * which imposes a limit of 99999 '?' placeholders POSIX style. Actual counts
|
||||
+ * are a bit higher:
|
||||
+ * using factor 5: :p1 .. :p1107
|
||||
+ * using factor 6: :p1 .. :p11106
|
||||
+ * using factor 7: :p1 .. :p111105
|
||||
+ * and that count is insane already */
|
||||
+ new_stmt_sv = newSV(strlen(statement) * 7 + 16);
|
||||
sv_setpv(new_stmt_sv,"");
|
||||
src = statement;
|
||||
dest = SvPVX(new_stmt_sv);
|
||||
@@ -4340,9 +4347,9 @@ preparse(SV *dbh, const char *statement, IV ps_return, IV ps_accept, void *foo)
|
||||
continue;
|
||||
}
|
||||
|
||||
- if ( !(*src==':' && (PS_accept(DBIpp_ph_cn) || PS_accept(DBIpp_ph_cs)))
|
||||
- && !(*src=='?' && PS_accept(DBIpp_ph_qm))
|
||||
- ){
|
||||
+ if ( !(*src==':' && (PS_accept(DBIpp_ph_cn) || PS_accept(DBIpp_ph_cs)))
|
||||
+ && !(*src=='?' && PS_accept(DBIpp_ph_qm))
|
||||
+ ){
|
||||
if (*src == '\'' || *src == '"')
|
||||
in_quote = *src;
|
||||
*dest++ = *src++;
|
||||
@@ -4361,12 +4368,18 @@ preparse(SV *dbh, const char *statement, IV ps_return, IV ps_accept, void *foo)
|
||||
if (PS_return(DBIpp_ph_qm))
|
||||
;
|
||||
else if (PS_return(DBIpp_ph_cn)) { /* '?' -> ':p1' (etc) */
|
||||
+ if (idx >= 99999) {
|
||||
+ char buf[99];
|
||||
+ sprintf(buf, "preparse found more than 99999 '?' placeholders. Limit exceeded.");
|
||||
+ set_err_char(dbh, imp_xxh, "1", 1, buf, 0, "preparse");
|
||||
+ return &PL_sv_undef;
|
||||
+ }
|
||||
sprintf(start,":p%d", idx++);
|
||||
dest = start+strlen(start);
|
||||
}
|
||||
else if (PS_return(DBIpp_ph_sp)) { /* '?' -> '%s' */
|
||||
- *start = '%';
|
||||
- *dest++ = 's';
|
||||
+ *start = '%';
|
||||
+ *dest++ = 's';
|
||||
}
|
||||
}
|
||||
else if (isDIGIT(*src)) { /* :1 */
|
||||
@@ -4374,24 +4387,24 @@ preparse(SV *dbh, const char *statement, IV ps_return, IV ps_accept, void *foo)
|
||||
style = ":1";
|
||||
|
||||
if (PS_return(DBIpp_ph_cn)) { /* ':1'->':p1' */
|
||||
- idx = pln;
|
||||
- *dest++ = 'p';
|
||||
- while(isDIGIT(*src))
|
||||
- *dest++ = *src++;
|
||||
+ idx = pln;
|
||||
+ *dest++ = 'p';
|
||||
+ while(isDIGIT(*src))
|
||||
+ *dest++ = *src++;
|
||||
}
|
||||
else if (PS_return(DBIpp_ph_qm) /* ':1' -> '?' */
|
||||
|| PS_return(DBIpp_ph_sp) /* ':1' -> '%s' */
|
||||
) {
|
||||
- PS_return(DBIpp_ph_qm) ? sprintf(start,"?") : sprintf(start,"%%s");
|
||||
- dest = start + strlen(start);
|
||||
- if (pln != idx) {
|
||||
- char buf[99];
|
||||
- sprintf(buf, "preparse found placeholder :%d out of sequence, expected :%d", pln, idx);
|
||||
- set_err_char(dbh, imp_xxh, "1", 1, buf, 0, "preparse");
|
||||
- return &PL_sv_undef;
|
||||
- }
|
||||
- while(isDIGIT(*src)) src++;
|
||||
- idx++;
|
||||
+ PS_return(DBIpp_ph_qm) ? sprintf(start,"?") : sprintf(start,"%%s");
|
||||
+ dest = start + strlen(start);
|
||||
+ if (pln != idx) {
|
||||
+ char buf[99];
|
||||
+ sprintf(buf, "preparse found placeholder :%d out of sequence, expected :%d", pln, idx);
|
||||
+ set_err_char(dbh, imp_xxh, "1", 1, buf, 0, "preparse");
|
||||
+ return &PL_sv_undef;
|
||||
+ }
|
||||
+ while(isDIGIT(*src)) src++;
|
||||
+ idx++;
|
||||
}
|
||||
}
|
||||
else if (isALNUM(*src)) /* :name */
|
||||
@ -34,13 +34,15 @@
|
||||
|
||||
Name: perl-DBI
|
||||
Version: 1.641
|
||||
Release: 5%{?dist}
|
||||
Release: 6%{?dist}
|
||||
Summary: A database access API for perl
|
||||
License: GPL+ or Artistic
|
||||
URL: http://dbi.perl.org/
|
||||
Source0: http://www.cpan.org/authors/id/T/TI/TIMB/DBI-%{version}.tar.gz
|
||||
# RHEL-184974, CVE-2026-9698, Fix stack overflow and buffer overflow in DBI.xs
|
||||
Patch0: DBI-1.641-Fix-CVE-2026-9698.patch
|
||||
# RHEL-193298, CVE-2026-14739, Heap overflow when preparsing SQL statements with excessive placeholders
|
||||
Patch1: DBI-1.643-Fix-CVE-2026-14739.patch
|
||||
BuildRequires: coreutils
|
||||
BuildRequires: findutils
|
||||
BuildRequires: gcc
|
||||
@ -220,6 +222,10 @@ make test
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Tue Jul 28 2026 Michal Josef Špaček <mspacek@redhat.com> - 1.641-6
|
||||
- Fix heap overflow when preparsing SQL statements with excessive placeholders (CVE-2026-14739)
|
||||
Resolves: RHEL-193298
|
||||
|
||||
* Mon Jun 22 2026 Michal Josef Špaček <mspacek@redhat.com> - 1.641-5
|
||||
- Fix stack overflow and buffer overflow in DBI.xs (CVE-2026-9698)
|
||||
Resolves: RHEL-184974
|
||||
|
||||
Loading…
Reference in New Issue
Block a user