June 1, 2026·4 min read·engineeringperlsecurityregex

Perl 5.43.11 fixes byte sizing in regular-expression compilation

CVE-2026-8376 concerns a heap buffer overflow while compiling repeated fixed strings on 32-bit Perl builds. The patch checks byte arithmetic before the compiler allocates its joined substring buffer.

Perl 5.43.11 is out today, June 1, according to the release history. Its release notes include the repair for CVE-2026-8376 in Perl_study_chunk. The defect confused character counts with byte requirements in the regular-expression compiler. The interesting operational detail is that compilation itself can reach the unsafe operation, before an application begins matching its subject text.

Regular expressions are a substantial reason I still use Perl for one-off text work. Matching and substitution are part of the language, which makes short transformations convenient to express. I would distinguish that preference from permission to accept arbitrary patterns from another party. A program that owns its pattern and a program that compiles a supplied pattern expose different behavior to their callers.

Compilation crosses the trust boundary

The CPANSec disclosure published before this release describes a heap buffer overflow on 32-bit builds through 5.43.10. A large minimum repetition count applied to a fixed substring could overflow the size calculation. The resulting allocation was too small for the copy that followed. CPANSec advised avoiding compilation of untrusted patterns on those builds until a fix was installed.

That description changes how I would assess exposure. A review that considers only the text searched by a regular expression misses control over the expression itself. If a caller supplies syntax that the application compiles, the caller can influence the compiler path. I would locate those compilation sites before deciding whether a service reaches this particular defect.

I would also avoid describing this as ordinary expensive matching. The disclosure identifies integer overflow followed by a heap buffer overflow during compilation. A limit on the duration of a subsequent search addresses another concern. It cannot establish that memory sizing during the earlier compilation step is correct. The phase where a defect occurs determines which proposed mitigation can be relevant.

For an inventory, the architecture of the Perl build matters. CPANSec names 32-bit builds, so I would verify the deployed interpreter instead of inferring its properties from a development laptop. A working test on another architecture does not establish that the affected arithmetic is safe in the target package. The package supplier needs to identify whether its build contains the fix.

Character length does not size a byte buffer

Perl documents this distinction in its Unicode documentation for 5.43.11. String operations generally use character semantics, while a character can require more than one byte in its representation. A character count is therefore not interchangeable with the size needed for copying a byte sequence. This is a familiar distinction at application boundaries, and it also applies inside the interpreter.

The upstream patch adds checks around the actual added byte length. In the surrounding code, l is adjusted to represent the added string length after the existing prefix. The new guard handles the case where that length is positive and rejects arithmetic that would exceed SSize_t_MAX.

The guard checks the multiplication using division before it evaluates the product in the later condition. It also checks whether adding the existing length would exceed the same maximum. When either condition holds, it reports Regexp out of space. This ordering matters because checking only after overflowing a size expression would already have lost the information needed to size the allocation correctly.

I would preserve both checks in any explanation of the repair. Repetition determines the amount of new data, while the existing prefix contributes to the final buffer requirement. A multiplication that fits does not by itself prove that the subsequent addition fits. The implementation has to validate the complete size expression used by the operation.

This is also why I would resist a workaround that simply assumes character count is a conservative allocation estimate. In a variable-width representation, it can underestimate the byte requirement. The patch uses the unit relevant to the buffer operation and tests the arithmetic before proceeding. That is the part an implementation review needs to establish.

The regression test targets the affected build

The patch also changes a regression test. Its architecture condition skips the cases unless the pointer size is four bytes, with a comment that the cases use too much memory on the wider build. The change removes a temporary expected-failure marker from a case that should now report the space error.

I would take that test design seriously when reproducing the fix. The purpose is to verify a bounded rejection in the affected configuration. Running a large repetition case on an arbitrary machine can exercise a different resource limit and provide less useful evidence. The upstream condition explains why the architecture belongs in the test description.

For application verification, I would use the supplier-approved test procedure and inspect the final error behavior. If an application compiles caller-provided patterns, a rejected pattern needs to become an ordinary handled failure. A corrected interpreter does not establish that the surrounding application reports compilation failures appropriately. That behavior deserves a separate application test.

I would record the interpreter package and architecture with the result. A statement that a pattern was rejected, without identifying the build, is difficult to reuse during a later upgrade. The same test input can have a different resource consequence under a different size model. Keeping that context prevents a future maintainer from interpreting an architecture-specific check as universal coverage.

I would keep the relevant package advisory with that test record so the provenance of the fix remains available during review. The development release now includes this repair. I would still require separate evidence before asserting that a deployed stable package contains it, since the 5.43.11 release record describes that development version. For a system that compiles untrusted expressions, the acceptance decision should identify the corrected package or applied upstream patch and retain the observed rejection behavior for the target build.