diff --git a/DBI-1.643-Fix-CVE-2026-14380.patch b/DBI-1.643-Fix-CVE-2026-14380.patch new file mode 100644 index 0000000..7b6035a --- /dev/null +++ b/DBI-1.643-Fix-CVE-2026-14380.patch @@ -0,0 +1,27 @@ +From 7828ba189dbefb73aa53dd5de5207d887c85ba18 Mon Sep 17 00:00:00 2001 +From: Robert Rothenberg +Date: Wed, 1 Jul 2026 22:31:56 +0100 +Subject: [PATCH] Load profile packages using Module::Load [CVE-2026-14380] + +--- + lib/DBI/Profile.pm | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/lib/DBI/Profile.pm b/lib/DBI/Profile.pm +index f2cc886..b6d8f0c 100644 +--- a/lib/DBI/Profile.pm ++++ b/lib/DBI/Profile.pm +@@ -758,7 +758,12 @@ sub _auto_new { + } + } + +- eval "require $package" if $package; # silently ignores errors ++ eval { ++ if ($package) { ++ (my $file = "$package.pm") =~ s{::}{/}g; ++ require $file; # silently ignores errors ++ } ++ }; + $package ||= $class; + + return $package->new(Path => \@Path, @args); diff --git a/DBI-1.643-Fix-CVE-2026-14739.patch b/DBI-1.643-Fix-CVE-2026-14739.patch new file mode 100644 index 0000000..95837df --- /dev/null +++ b/DBI-1.643-Fix-CVE-2026-14739.patch @@ -0,0 +1,128 @@ +From 877297ada6974a4f35db2cb30ee3f32a8c50bca3 Mon Sep 17 00:00:00 2001 +From: "H.Merijn Brand - Tux" +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 + 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 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 + +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 */ diff --git a/perl-DBI.spec b/perl-DBI.spec index 1ec622e..675686e 100644 --- a/perl-DBI.spec +++ b/perl-DBI.spec @@ -34,7 +34,7 @@ Name: perl-DBI Version: 1.643 -Release: 26%{?dist}.1 +Release: 26%{?dist}.3 Summary: A database access API for perl License: GPL-1.0-or-later OR Artistic-1.0-Perl URL: http://dbi.perl.org/ @@ -46,6 +46,10 @@ Patch2: DBI-1.643-Catch-warning.patch Patch3: DBI-1.643-Document-the-new-behavior-for-f_dir.patch # RHEL-184980, CVE-2026-9698, Fix possible stack overflow and buffer overflow in DBI.xs Patch4: DBI-1.643-Fix-CVE-2026-9698.patch +# RHEL-193293, CVE-2026-14739, Set a hard limit of 99999 on '?' placeholders +Patch5: DBI-1.643-Fix-CVE-2026-14739.patch +# RHEL-211146, CVE-2026-14380, Load profile packages using Module::Load +Patch6: DBI-1.643-Fix-CVE-2026-14380.patch BuildRequires: coreutils BuildRequires: findutils BuildRequires: gcc @@ -279,6 +283,14 @@ make test %{_libexecdir}/%{name} %changelog +* Thu Jul 16 2026 RHEL Packaging Agent - 1.643-26.3 +- Fix CVE-2026-14380: unsafe string eval in DBI::Profile +- Resolves: RHEL-211146 + +* Fri Jul 10 2026 RHEL Packaging Agent - 1.643-26.2 +- Fix CVE-2026-14739: set a hard limit of 99999 on '?' placeholders +- Resolves: RHEL-193293 + * Fri Jun 19 2026 RHEL Packaging Agent - 1.643-26.1 - Fix CVE-2026-9698: stack overflow and buffer overflow in DBI.xs - Resolves: RHEL-184980