April 14, 2018·4 min read·engineeringperlsecurityregex

Perl 5.26.2 repairs regex and pack memory errors

Perl 5.26.2 fixes distinct memory errors in regular expressions and binary packing, alongside parser and reference-counting repairs.

Perl 5.26.2 fixes memory errors in operations that turn compact descriptions into internal work. Regular expressions describe matching, and pack templates describe binary representations. The release notes identify crafted expressions and a large packing item count as inputs that could take those operations beyond their allocated heap buffers. The security implications differ between the reported read and write errors.

The history shipped with the release dates it to April 14. This maintenance release describes no intentionally incompatible changes from 5.26.1. Its security repairs therefore arrive as corrections to existing behaviour, alongside other fixes to parsing and interpreter state.

I favour Perl for one-off text manipulation, so regular expressions are central to its appeal for me. Their integration into the grammar removes work from the calling code, but leaves the interpreter responsible for compiling and executing them safely. These fixes concern that responsibility at the memory-management level.

Compilation and matching expose different failures

CVE-2018-6797 concerns a heap-buffer write overflow in S_regatom, in regcomp.c. The notes say a crafted regular expression could trigger the overflow with control over the bytes written. The relevant input is the expression itself. A service that accepts a pattern from another party presents a different interface from one that uses a fixed pattern solely against external subject text.

That distinction follows directly from the stated trigger. Calling every regular-expression bug a risk from arbitrary matched text would obscure where this one occurs. Compilation is already work performed on the pattern, before the application obtains a matching result. The release notes do not establish a complete exploitation sequence, and a write overflow should not be described as a demonstrated compromise of every application that uses regular expressions.

CVE-2018-6798 is a heap-buffer read overflow in Perl__byte_dump_string, in utf8.c. The documented trigger is matching a crafted locale-dependent regular expression. The notes identify potential information disclosure. A read beyond a buffer has a different immediate effect from a write beyond one, even though both arise in the regular-expression facilities.

Locale dependence is part of that description. Omitting it would broaden the claim beyond the evidence supplied by the release. Conversely, describing the problem as only a matching correctness issue would understate it, because the notes explicitly identify the memory read and possible disclosure. The practical explanation needs both the trigger and the type of memory error.

There is also a repaired assertion failure in Perl__core_swash_init. Control characters in a supposed Unicode property name could crash Perl. This item does not carry one of the three CVE identifiers in the notes, but it reinforces that the interpreter must handle malformed pattern-related descriptions safely. The announced result is a crash fix, without an accompanying claim of information disclosure or controlled writes.

Binary packing has its own size calculations

CVE-2018-6913 concerns S_pack_rec. The release notes say pack() could write beyond a heap buffer when given a large item count. The function documentation in the release defines pack as conversion of a list of values into a string according to a template. Its result concatenates the converted representations.

A template is consequently more than a label on an existing string. It determines the conversion operations and the representation the function constructs. Item counts participate in how much work and output the operation describes. The security repair belongs to that implementation, where the requested representation must fit the memory allocated for it.

The documented directives also make binary format choices explicit. N represents an unsigned 32-bit value in network byte order. V represents an unsigned 32-bit value in little-endian order. Native integer directives have their own documented sizes and platform conditions. These details explain why the function is useful for binary data, but the release does not claim that choosing one ordinary directive over another is a general workaround for the overflow.

The supplied fix description does not provide the large count or a complete reproducer. It would be misleading to invent a threshold and present it as a property of the vulnerable versions. The supported conclusion is that the maintenance release repairs the large-item-count write overflow in this operation.

Parser recovery also needs a safe stopping point

Several non-CVE fixes address what happens when parsing fails or unusual syntax changes interpreter state. In string interpolation and the replacement side of s///e, a failed nested compilation now stops compilation earlier. Previously, Perl could continue to look for further errors while partly parsed constructs remained on the parser stack. The resulting confusion could crash the interpreter.

Collecting more errors is normally useful, but only while the parser retains a valid state from which to continue. This repair changes that decision at the failed nested parse. It avoids asking a damaged intermediate parse to support more diagnostic work. The release notes identify the stack state that made the earlier recovery unsafe.

A separate readpipe() fix checks at compile time that the function receives one parameter expression and gives that expression scalar context. The notes tie the correction to avoiding runtime stack corruption. The function documentation explains that readpipe executes a command and collects its output, with scalar and list contexts affecting the returned result. Here, repaired parameter handling concerns the expression supplied to the call, which is a separate question from the context of its result.

The release also corrects reference counting when sort aliases $a and $b. Re-aliasing during the comparator could previously cause premature destruction or leaked scalars. These changes repair the interpreter behaviour beneath familiar constructs, even where the application never allocates or frees memory explicitly.

I regard the compatibility promise in a maintenance release as especially useful here. Programs should receive the corrected memory handling without adopting a new programming model. The notes still distinguish the three security failures, the Unicode-property crash, and the parser and aliasing repairs, so operators can relate each correction to the constructs their programs use.