This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
avoid double-freeing regex code blocks
authorDavid Mitchell <davem@iabyn.com>
Wed, 1 Feb 2017 15:50:14 +0000 (15:50 +0000)
committerDavid Mitchell <davem@iabyn.com>
Wed, 1 Feb 2017 16:09:07 +0000 (16:09 +0000)
commitf8def6c7f38b614db0e8ac0ba76999e9b8cfd1d6
tree1cd07aad8b9ed74e2bbb3154195fe15da2244eb1
parentdc0dad9b91adb09c774c7248bc91a44b7a777d4d
avoid double-freeing regex code blocks

RT #130650 heap-use-after-free in S_free_codeblocks

When compiling qr/(?{...})/, a reg_code_blocks structure is allocated
and various SVs are attached to it. Initially this is set to be freed
via a destructor on the savestack, in case of early dying. Later the
structure is attached to the compiling regex, and a boolean flag in the
structure, 'attached', is set to true to show that the destructor no
longer needs to free the struct.

However, it is possible to get three orders of destruction:

1) allocate, push destructor, die early
2) allocate, push destructor, attach to regex, die
2) allocate, push destructor, attach to regex, succeed

In 2, the regex is freed (via the savestack) before the destructor is
called. In 3, the destructor is called, then later the regex is freed.

It turns out perl can't currently handle case 2:

    qr'(?{})\6'

Fix this by turning the 'attached' boolean field into an integer refcount,
then keep a count of whether the struct is referenced from the savestack
and/or the regex. Since it normally has a value of 1 or 2, it's similar
to a boolean flag, but crucially it no longer just indicates that the
regex has a pointer to it ('attached'), but that at least one of the
savestack and regex have a pointer to it. So order of freeing no longer
matters.

I also updated S_free_codeblocks() so that it nulls out SV pointers in
the reg_code_blocks struct before freeing them. This is is generally good
practice to avoid double frees, although is probably not needed at the
moment.
regcomp.c
regexp.h
t/re/pat_re_eval.t