java-topology/whitepaper/outreach/perl5.md

2.7 KiB
Raw Blame History

Perl 5 — CWE-407 Disclosure Brief

2026-03-27 · Patch available — awaiting upstream merge

Finding

One O(n²) defect in the Perl 5 interpreter's pad (lexical variable) lookup. S_pad_findlex() in pad.c:1168 performs an O(N) reverse scan over pad name entries for every lexical variable reference, causing O(N²) compile-time overhead for subroutines with many lexicals. Patch ready for upstream review.

The Defects

perl5-0001 (PATCHED — HIGH): pad.c:1168

/* S_pad_findlex() — per lexical variable reference: */
STATIC PADOFFSET
S_pad_findlex(pTHX_ const char *namepv, STRLEN namelen, U32 flags,
              const CV* cv, U32 seq, int warn, SV** out_capture,
              SV** out_name_sv, int *out_flags)
{
    /* O(N) reverse scan over pad names per reference */
    I32 offset = PadnamelistMAXNAMED(PL_comppad_name);
    while (offset > 0) {
        SV * const sv = PAD_COMPNAME_SV(offset);
        /* ... compare name ... */
        offset--;
    }
}

Linear reverse scan over all N pad name entries per lexical reference. For N lexical variables and R references: O(R × N) compile-time cost.

Complexity Proof

For N lexical variables in a subroutine:

  • Per variable reference: O(N) reverse scan
  • Total: O(R × N) — scales with lexical count
  • Fixed: padname_string → offset hash map in PADNAMELIST → O(1) per reference

Impact

All Perl 5 code with lexically-scoped variables — every non-trivial Perl subroutine. Perl 5 is the most widely deployed dynamic language in legacy enterprise systems, web backends (Perl/CGI, Catalyst, Dancer), sysadmin scripts, and bioinformatics. Subroutines with many my variables and complex lexical capture chains hit worst case during compilation. The defect is compile-time only.

The Fix

Add a padname_string → offset hash map in PADNAMELIST:

/* Before */
/* O(N) reverse scan */
I32 offset = PadnamelistMAXNAMED(PL_comppad_name);
while (offset > 0) {
    if (namematch(PAD_COMPNAME_SV(offset), namepv, namelen)) return offset;
    offset--;
}

/* After */
/* CWE-407 fix: hash map for O(1) pad name lookup instead of O(N) reverse scan. */
PADOFFSET result = padnamelist_hash_lookup(PL_comppad_name, namepv, namelen, seq);
if (result != NOT_IN_PAD) return result;

Patch

defects/perl5/patch/perl5-0001-pad-findlex-hashmap.patch

What We Ask

  1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
  2. Validate the patch against your pad and lexical variable test suite.
  3. Assess CVE eligibility — compile-time overhead for subroutines with many lexicals.
  4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.