prevent leak of class name from retrieve_hook() on an exception
authorTony Cook <tony@develop-help.com>
Mon, 6 Feb 2017 00:38:10 +0000 (11:38 +1100)
committerTony Cook <tony@develop-help.com>
Mon, 6 Feb 2017 00:38:10 +0000 (11:38 +1100)
If supplied with a large class name, retrieve_hook() allocates
buffer for the class name and Safefree()s it on exit path.

Unfortunately this memory leaks if load_module() (or a couple of other
code paths) throw an exception.

So use SAVEFREEPV() to release the memory instead.

==20183== 193 bytes in 1 blocks are definitely lost in loss record 4 of 6
==20183==    at 0x4C28C20: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20183==    by 0x55F85D: Perl_safesysmalloc (util.c:153)
==20183==    by 0x6ACA046: retrieve_hook (Storable.xs:4265)
==20183==    by 0x6AD6D19: retrieve (Storable.xs:6217)
==20183==    by 0x6AD8144: do_retrieve (Storable.xs:6401)
==20183==    by 0x6AD85B7: pretrieve (Storable.xs:6506)
==20183==    by 0x6AD8E14: XS_Storable_pretrieve (Storable.xs:6718)
==20183==    by 0x5C176D: Perl_pp_entersub (pp_hot.c:4227)
==20183==    by 0x55E1C6: Perl_runops_debug (dump.c:2450)
==20183==    by 0x461B79: S_run_body (perl.c:2528)
==20183==    by 0x46115C: perl_run (perl.c:2451)
==20183==    by 0x41F1CD: main (perlmain.c:123)

dist/Storable/Storable.xs

index 829c5d7..9ba48be 100644 (file)
@@ -4281,6 +4281,11 @@ static SV *retrieve_hook(pTHX_ stcxt_t *cxt, const char *cname)
 
        TRACEME(("class name: %s", classname));
 
+       if (!(flags & SHF_IDX_CLASSNAME) && classname != buf) {
+                /* some execution paths can throw an exception */
+               SAVEFREEPV(classname);
+        }
+
        /*
         * Decode user-frozen string length and read it in an SV.
         *
@@ -4400,8 +4405,6 @@ static SV *retrieve_hook(pTHX_ stcxt_t *cxt, const char *cname)
                SEEN0_NN(sv, 0);
                SvRV_set(attached, NULL);
                SvREFCNT_dec(attached);
-               if (!(flags & SHF_IDX_CLASSNAME) && classname != buf)
-                   Safefree(classname);
                return sv;
            }
            CROAK(("STORABLE_attach did not return a %s object", classname));
@@ -4482,8 +4485,6 @@ static SV *retrieve_hook(pTHX_ stcxt_t *cxt, const char *cname)
        SvREFCNT_dec(frozen);
        av_undef(av);
        sv_free((SV *) av);
-       if (!(flags & SHF_IDX_CLASSNAME) && classname != buf)
-               Safefree(classname);
 
        /*
         * If we had an <extra> type, then the object was not as simple, and