diff mbox series

[meta-oe,wrynose,5/5] libdbi-perl: fix CVE-2026-108518

Message ID 20261111053834.3702246-5-dkelaiya@cisco.com
State New
Headers show
Series [meta-oe,wrynose,1/5] libdbi-perl: fix CVE-2026-78030 | expand

Commit Message

From: Darsh Kelaiya <dkelaiya@cisco.com>

Backport the destructor profiling fix [1] to DBI 1.647 for the
type-confusion crash described in [2]. Accept the inner handle
returned as either a reference or a raw hash during destruction.

Retain the upstream regression and update the older profiling
test's fixed plan to account for the two added assertions.

[1] https://github.com/perl5-dbi/dbi/commit/c2ff4df575d7af625bb4d0d1ef7539f90b22d8b2
[2] https://github.com/perl5-dbi/dbi/security/advisories/GHSA-7393-6f8r-fhh3

Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
---
 .../perl/libdbi-perl/CVE-2026-108518.patch    | 72 +++++++++++++++++++
 .../perl/libdbi-perl_1.647.bb                 |  1 +
 2 files changed, 73 insertions(+)
 create mode 100644 meta-oe/recipes-devtools/perl/libdbi-perl/CVE-2026-108518.patch
diff mbox series

Patch

diff --git a/meta-oe/recipes-devtools/perl/libdbi-perl/CVE-2026-108518.patch b/meta-oe/recipes-devtools/perl/libdbi-perl/CVE-2026-108518.patch
new file mode 100644
index 0000000000..9ec454909a
--- /dev/null
+++ b/meta-oe/recipes-devtools/perl/libdbi-perl/CVE-2026-108518.patch
@@ -0,0 +1,72 @@ 
+From c2ff4df575d7af625bb4d0d1ef7539f90b22d8b2 Mon Sep 17 00:00:00 2001
+From: "H.Merijn Brand - Tux" <linux@tux.freedom.nl>
+Date: Fri, 9 Oct 2026 16:04:53 +0200
+Subject: [PATCH] Prevent dbi_profile crash (Henrik Teichmann)
+
+CVE: CVE-2026-108518
+Upstream-Status: Backport [https://github.com/perl5-dbi/dbi/commit/c2ff4df575d7af625bb4d0d1ef7539f90b22d8b2]
+
+Backport Changes:
+- Place the new assertions before the older test's exit and update
+  its fixed test plan from 60 to 62; newer subtests are absent.
+- Omit release notes, generated Changes.pm, and dbixs_rev.h updates.
+
+Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
+---
+ DBI.xs        |  8 +++++++-
+ t/40profile.t | 16 +++++++++++++++-
+ 2 files changed, 22 insertions(+), 2 deletions(-)
+
+diff --git a/DBI.xs b/DBI.xs
+index 2bef3cb..a42b597 100644
+--- a/DBI.xs
++++ b/DBI.xs
+@@ -3031,7 +3031,13 @@ dbi_profile(SV *h, imp_xxh_t *imp_xxh, SV *statement_sv, SV *method, NV t1, NV t
+                         dbh_outer_hv = DBIc_MY_H(imp_dbh);
+                         if (SvTYPE(dbh_outer_hv) != SVt_PVHV)
+                             return &PL_sv_undef;        /* presumably global destruction - bail */
+-                        dbh_inner_hv = (HV*)SvRV(dbih_inner(aTHX_ (SV*)dbh_outer_hv, "profile"));
++                        {   /* dbih_inner() returns the inner handle as an RV, except when it was
++                             * given a raw inner HV (DBIc_MY_H() is set to the inner HV while the
++                             * outer handle is being destroyed): then it returns that HV itself,
++                             * and SvRV() on it would return its bucket array (HvARRAY). */
++                            SV *irv = dbih_inner(aTHX_ (SV*)dbh_outer_hv, "profile");
++                            dbh_inner_hv = (HV*)(SvROK (irv) ? SvRV (irv) : irv);
++                        }
+                         if (SvTYPE(dbh_inner_hv) != SVt_PVHV)
+                             return &PL_sv_undef;        /* presumably global destruction - bail */
+                     }
+diff --git a/t/40profile.t b/t/40profile.t
+index 7a71b8f..1eb3151 100644
+--- a/t/40profile.t
++++ b/t/40profile.t
+@@ -31,7 +31,7 @@ BEGIN {
+         if $Config{osvers} =~ /xen/ # eg 2.6.18-4-xen-amd64
+         and $ENV{AUTOMATED_TESTING};
+ 
+-    plan tests => 60;
++    plan tests => 62;
+ }
+ 
+ $Data::Dumper::Indent = 1;
+@@ -458,6 +458,20 @@ is("@$totals", "27.00 2.93 0.11 0.01 0.23 1023110000.00 1023110010.00",
+    'merged time foo/bar');
+ is($total_time, 2.93, 'merged nodes foo/bar time');
+ 
++# The DESTROY of a database handle must be profiled when the Path has {attr} elements.
++# While the outer handle is being destroyed DBIc_MY_H() holds the raw inner HV; dbi_profile() used to
++# call SvRV() on the (raw HV) result of dbih_inner() and so used the hash's bucket array as an HV.
++{
++    my $prof = DBI::Profile->new(Path => [ '{Username}', '!MethodName' ]);
++    my $dbh = DBI->connect("dbi:ExampleP:", 'usrnam', '', { RaiseError => 1, Profile => $prof });
++    $dbh->ping;
++    undef $dbh; # DESTROY of the database handle
++    my $node = $prof->{Data}{usrnam};
++    ok $node && $node->{DESTROY}, 'DESTROY of a database handle is profiled with a {Username} path element';
++    is $node && $node->{DESTROY} ? $node->{DESTROY}[0] : undef, 1, 'exactly one DESTROY call profiled';
++    $prof->{Data} = undef; # no report at exit
++}
++
+ exit 0;
+ 
+ 
diff --git a/meta-oe/recipes-devtools/perl/libdbi-perl_1.647.bb b/meta-oe/recipes-devtools/perl/libdbi-perl_1.647.bb
index 0b444a7980..5c0826a01b 100644
--- a/meta-oe/recipes-devtools/perl/libdbi-perl_1.647.bb
+++ b/meta-oe/recipes-devtools/perl/libdbi-perl_1.647.bb
@@ -25,6 +25,7 @@  SRC_URI = "${CPAN_MIRROR}/authors/id/H/HM/HMBRAND/DBI-${PV}.tgz \
            file://CVE-2026-88815_p1.patch \
            file://CVE-2026-88815_p2.patch \
            file://CVE-2026-88816.patch \
+           file://CVE-2026-108518.patch \
            "
 SRC_URI[sha256sum] = "0df16af8e5b3225a68b7b592ab531004ddb35a9682b50300ce50174ad867d9aa"