summaryrefslogtreecommitdiff
path: root/embed.h
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2021-09-11 09:23:37 +0000
committerNicholas Clark <nick@ccl4.org>2021-09-23 15:27:33 +0000
commit07024caa60f04ae203801d222536bfdad4caf7e8 (patch)
treead78a8da3ee531b4992c002c10733e1eb4703da7 /embed.h
parent2c205b5406a70a5753a289ca1b05dace7c12727a (diff)
downloadperl-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