2.7 KiB
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 → offsethash map inPADNAMELIST→ 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
- Confirm receipt and assign a GitHub Security Advisory or issue reference.
- Validate the patch against your pad and lexical variable test suite.
- Assess CVE eligibility — compile-time overhead for subroutines with many lexicals.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.