Subject: | leak and double free in CSV_XS.xs hook() |
Date: | Fri, 15 Jun 2018 13:30:37 +0100 |
To: | bug-Text-CSV_XS [...] rt.cpan.org |
From: | Dave Mitchell <davem [...] iabyn.com> |
This code in hook() in CSV_XS.xs is problematic in two ways:
XPUSHs (newRV_noinc ((SV *)hv));
XPUSHs (newRV_noinc ((SV *)av));
First, the newly-created RVs will leak, since they're not mortalised,
and perl's arg stack isn't reference counted.
Secondly, because the reference count of hv and av aren't increased,
they may be prematurely freed and perl may subsequently crash.
In fact, this is happening in
https://rt.perl.org/Ticket/Display.html?id=133270
In a stripped-down t/82_free_unref_scalar.t from DBD::CSV, I see
1) the RV created by newRV_noinc ((SV *)av) lasting until global
destruction;
2) in the meantime, the AV it points to is (prematurely) freed, and the
SV later happens to be reallocated as an HV which happens to survive
until global destruction;
3) When the RV is eventually freed during global destruction, it triggers
a double free of that new HV.
I suspect you instead want something like
mXPUSHs (newRV_inc ((SV *)hv));
mXPUSHs (newRV_inc ((SV *)av));
--
The Enterprise is involved in a bizarre time-warp experience which is in
some way unconnected with the Late 20th Century.
-- Things That Never Happen in "Star Trek" #14