Skip to content

GHSA-f4qx-mr9m-q2hq

CVE Information

Summary

DBI 1.653 (current CPAN release) has two reproducible SIGSEGVs reachable from documented public interfaces. Both share the same underlying pattern: reading SvPVX(sv) on an SV that is not guaranteed to be SvPOK, so on IV-only/NV-only scalars a NULL-or-garbage pointer is fed to downstream C code (grok_number and hv_fetch).

Both crash the interpreter (SIGSEGV, exit 139) with 100% reproducibility on released 1.653 built against Perl 5.40.1 on x86_64 Linux, and both remain on current master (9603cbb). Impact class matches prior DBI advisories CVE-2019-20919 and CVE-2026-60082.


Bug 2 — $dbh->{FetchHashKeyName} = 42; $sth->fetchrow_hashref segfaults

Location: DBI.xs fetchrow_hashref (~line 5307 on master):

if (!keyattrib || !*keyattrib) {
    SV *kn = DBIc_FetchHashKeyName(imp_sth);
    if (kn && SvOK(kn))
        keyattrib = SvPVX(kn);
    else
        keyattrib = "NAME";
}
ka_rv = *hv_fetch((HV*)DBIc_MY_H(imp_sth), keyattrib, strlen(keyattrib), TRUE);

SvOK(kn) does not imply SvPOK(kn). When FetchHashKeyName has been set to a numeric value, SvPVX(kn) returns garbage, and strlen(keyattrib) plus hv_fetch walks past the end of that pointer.

Reproducer (100% reliable, exit=139; needs only DBD::ExampleP which ships with DBI):

perl -MDBI -e '
    my $dbh = DBI->connect("dbi:ExampleP:", "", "",
                           {RaiseError=>0,PrintError=>0});
    $dbh->{FetchHashKeyName} = 42;
    my $s = $dbh->prepare("select mode,size,name from .");
    $s->execute;
    $s->fetchrow_hashref;
'

Impact: FetchHashKeyName is a documented, writeable per-handle attribute. Assigning a non-string value — easy to do accidentally from configuration parsing, ORM code, or a counter/enum — crashes the interpreter the next time any hashref-fetching method runs. Likely also affects fetchall_hashref / selectall_hashref (share the key-derivation code), not separately verified.

Adjacent quirk (not a crash): FetchHashKeyName = "NAME\0garbage" silently accepts only the "NAME" prefix due to the same strlen(). Related to but distinct from open issue #45.

Suggested fix:

if (kn && SvOK(kn)) {
    STRLEN kn_len;
    keyattrib = SvPV(kn, kn_len);   /* forces stringification */
    /* and pass kn_len to hv_fetch instead of strlen(keyattrib) */
}

Environment

  • Perl 5.40.1, x86_64 GNU/Linux
  • DBI built from tag 1.653 and current master 9603cbb
  • make test (9834 tests) passes before either reproducer runs; neither reproducer path is exercised by the existing suite

Discovery

Manual review that swept SvPVX(...) sites for missing SvPOK guarantees. Same pattern may exist elsewhere in DBI.xs; these two are the ones I could turn into reliable crashes without a third-party DBD.

Not in scope of this advisory (mentioned for completeness)

  • DBI::_concat_hash_sorted silently corrupts hash keys with embedded NULs; causes cache-key collisions in connect_cached/prepare_cached
  • DBI::hash($buf, $type) truncates at NUL contrary to POD; propagates into err_hash
  • Driver.xst selectall_arrayref / selectrow_arrayref deref mg_find(SvRV(sth),'P')->mg_obj without NULL check; needs a compiled DBD to exercise