diff options
author | Nicholas Clark <nick@ccl4.org> | 2021-09-11 09:23:37 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2021-09-23 15:27:33 +0000 |
commit | 07024caa60f04ae203801d222536bfdad4caf7e8 (patch) | |
tree | ad78a8da3ee531b4992c002c10733e1eb4703da7 /embed.h | |
parent | 2c205b5406a70a5753a289ca1b05dace7c12727a (diff) | |
download | perl-07024caa60f04ae203801d222536bfdad4caf7e8.tar.gz |
Avoid leaking a scalar body after REGEXP to PVLV assignment
PVLV scalars are used to implement various obscure features of perl, such as
elements in tied hashes and hash lookups used as function parameters. To
make these work, PVLVs must be capable of holding all scalar types. First
class REGEXPs are larger than PVLVs, hence there is special case code to
attach REGEXP bodies to PVLVs, for code that both dereferences a regex object
and then assigns that value to a PVLV scalar. This was first implemented in
Oct 2012 by commit 8d919b0a35f2b57a:
Allow regexp-to-pvlv assignment
and improved in July 2017 with commit df6b4bd56551f2d3:
It turns out that the implementation would leak a scalar body, for the
"normal" use case (of this obscure feature). This wasn't noticed for two
reasons
1) bodies are allocated from arenas, and arenas are correctly freed during
full destruction.
2) the body is not leaked if the the PVLV scalar is then modified
The regression tests added by commit 8d919b0a35f2b57a were also testing
the corner case of concatenating to one of these values - ie that
sv_force_normal_flags() handled unwinding the special cases correctly.
To avoid code duplication, the tests added by that commit caused all PVLV
scalars to be passed to sv_force_normal_flags(), so didn't actually test
regular destruction of such scalars.
The tests added in Aug 2017 by commit 622c613e12cef84c:
PVLV-as-REGEXP: avoid PVX double free
With v5.27.2-30-gdf6b4bd, I changed the way that PVLVs store a regexp
value (by making the xpv_len field point to a regexp struct). There was a
bug in this, which caused the PVX buffer to be double freed.
Several REGEXP SVs can share a PVX buffer. Only one of them will have a
non-zero xpv_len field, and that SV gets to free the buffer.
After the commit above, the non-zero xpv_len was triggering an extra free.
This was showing up in smokes as failures in re/recompile.t when invoked
with PERL_DESTRUCT_LEVEL=2 (which t/TEST does).
were actually the first to expose this bug, even though it had been present
since 2012.
The bug is only visible with a full leak test (eg valgrind --leak-check=full
or an ASAN build) with -DPURIFY (to disable arenas), hence why it hasn't
been noticed.
Diffstat (limited to 'embed.h')
0 files changed, 0 insertions, 0 deletions