@@ -26,6 +26,7 @@ XS(XS_XSLoader_load) {
2626 SV * modfname , * modpname , * boots ;
2727 int modlibutf8 = 0 ;
2828
29+ ENTER ;
2930 if (items < 1 ) {
3031 modlibutf8 = HvNAMEUTF8 (stash );
3132 module = newSVpvn_flags (HvNAME (stash ), HvNAMELEN (stash ), modlibutf8 );
@@ -47,25 +48,35 @@ XS(XS_XSLoader_load) {
4748 boots = pv_copy (module );
4849 sv_catpvs (boots , "::bootstrap" );
4950 if ((bootc = get_cv (SvPV_nolen_const (boots ), 0 ))) {
51+ ENTER ; SAVETMPS ;
5052 PUSHMARK (MARK ); /* goto &$boots */
5153 PUTBACK ;
52- XSRETURN (call_sv (MUTABLE_SV (bootc ), GIMME ));
54+ items = call_sv (MUTABLE_SV (bootc ), GIMME );
55+ SPAGAIN ;
56+ FREETMPS ; LEAVE ;
57+ LEAVE ;
58+ XSRETURN (items );
5359 }
5460 if (!modlibname ) {
5561 modlibname = OutCopFILE (PL_curcop );
5662 if (memEQ (modlibname , "(eval " , 6 )) /* This catches RT #115808 */
5763 modlibname = NULL ;
5864 }
5965 if (!module ) {
66+ ENTER ; SAVETMPS ;
6067 PUSHMARK (MARK );
6168 PUTBACK ;
62- XSRETURN (call_pv ("XSLoader::bootstrap_inherit" , GIMME ));
69+ items = call_pv ("XSLoader::bootstrap_inherit" , GIMME );
70+ SPAGAIN ;
71+ PUTBACK ; FREETMPS ; LEAVE ;
72+ LEAVE ;
73+ XSRETURN (items );
6374 }
6475 modparts = dl_split_modparts (aTHX_ module );
6576 modfname = AvARRAY (modparts )[AvFILLp (modparts )];
6677 modpname = dl_construct_modpname (aTHX_ modparts );
67- DLDEBUG (3 ,PerlIO_printf (Perl_debug_log , " modpname (%s) => '%s'\n" ,
68- av_tostr (aTHX_ modparts ), modlibname ));
78+ DLDEBUG (3 ,PerlIO_printf (Perl_debug_log , " modpname (%s) => '%s','%s' \n" ,
79+ av_tostr (aTHX_ modparts ), modlibname , SvPVX ( modpname ) ));
6980 file = modlibname ? newSVpvn_flags (modlibname , strlen (modlibname ), modlibutf8 )
7081 : newSVpvs ("" );
7182
@@ -75,7 +86,7 @@ XS(XS_XSLoader_load) {
7586 if (items >= 1 ) {
7687 SV * caller = newSVpvn_flags (HvNAME (stash ), HvNAMELEN (stash ), modlibutf8 );
7788 modparts = dl_split_modparts (aTHX_ caller );
78- DLDEBUG (3 ,PerlIO_printf (Perl_debug_log , " caller %s => '%s' \n" ,
89+ DLDEBUG (3 ,PerlIO_printf (Perl_debug_log , " caller %s => (%s) \n" ,
7990 SvPVX (caller ), av_tostr (aTHX_ modparts )));
8091 }
8192 {
@@ -100,24 +111,52 @@ XS(XS_XSLoader_load) {
100111 }
101112 if (!SvCUR (file ))
102113 goto not_found ;
103- /* must be absolute. see RT #115808 */
114+ /* Must be absolute or in @INC. See RT #115808
115+ * Someone may have a #line directive that changes the file name, or
116+ * may be calling XSLoader::load from inside a string eval. We cer-
117+ * tainly do not want to go loading some code that is not in @INC,
118+ * as it could be untrusted.
119+ *
120+ * We could just fall back to DynaLoader here, but then the rest of
121+ * this function would go untested in the perl core, since all @INC
122+ * paths are relative during testing. That would be a time bomb
123+ * waiting to happen, since bugs could be introduced into the code.
124+ *
125+ * So look through @INC to see if $modlibname is in it. A rela-
126+ * tive $modlibname is not a common occurrence, so this block is
127+ * not hot code.
128+ */
104129 s = SvPVX_mutable (file );
105130 if (* s != '/'
106131#ifdef WINPATHSEP
107132 && * s != '\\'
108133 && !(* (s + 1 ) && (* (s + 1 ) == ':' ) && (* s >= 'A' && * s >= 'Z' ))
109134#endif
110- )
135+ ) {
136+ /* but allow relative file if in @INC */
137+ c = SvCUR (file )- 1 ;
138+ if (c < 1 ) goto not_found ;
139+ for (i = 0 ; i < AvFILL (GvAV (PL_incgv )); i ++ ) {
140+ SV * const dirsv = * av_fetch (GvAV (PL_incgv ), i , TRUE);
141+ SvGETMAGIC (dirsv );
142+ /* ignore av and cv refs here. they will be caught later in DynaLoader */
143+ if (SvPOK (dirsv )
144+ && SvCUR (dirsv ) >= (Size_t )c
145+ && memEQ (SvPVX (file ), SvPVX (dirsv ), c ))
146+ goto found ;
147+ }
111148 goto not_found ;
149+ }
112150 s = SvPVX_mutable (file ) + SvCUR (file ) - 1 ;
113- /* and must end with / */
151+ /* And must end with /. Disallow "." in @INC for local XS libs */
114152 if (* s != '/'
115153#ifdef WINPATHSEP
116154 && * s != '\\'
117155#endif
118156 )
119157 goto not_found ;
120158 }
159+ found :
121160 sv_catpv (file , "auto/" );
122161 sv_catsv (file , modpname );
123162 sv_catpv (file , "/" );
@@ -131,18 +170,29 @@ XS(XS_XSLoader_load) {
131170 } else {
132171 not_found :
133172 DLDEBUG (3 ,PerlIO_printf (Perl_debug_log , " not found '%s'\n" , SvPVX (file )));
173+ ENTER ; SAVETMPS ;
134174 if (items < 1 ) {
135175 PUSHMARK (SP );
136176 XPUSHs (module );
137177 } else {
138178 PUSHMARK (MARK );
139179 }
140180 PUTBACK ;
141- XSRETURN (call_pv ("XSLoader::bootstrap_inherit" , GIMME ));
181+ SvREFCNT_dec (file );
182+ items = call_pv ("XSLoader::bootstrap_inherit" , GIMME );
183+ SPAGAIN ;
184+ PUTBACK ; FREETMPS ; LEAVE ;
185+
186+ LEAVE ;
187+ XSRETURN (items );
142188 }
143189 if ((items = dl_load_file (aTHX_ ax , file , module , GIMME ))) {
190+ LEAVE ;
191+ SvREFCNT_dec (file );
144192 XSRETURN (items );
145193 } else {
194+ LEAVE ;
195+ SvREFCNT_dec (file );
146196 XSRETURN_UNDEF ;
147197 }
148198}
@@ -153,6 +203,7 @@ XS(XS_XSLoader_load_file) {
153203
154204 if (items < 2 )
155205 die ("Usage: XSLoader::load_file($module, $sofile)\n" );
206+ ENTER ; SAVETMPS ;
156207 module = ST (0 );
157208 file = ST (1 );
158209
@@ -163,8 +214,10 @@ XS(XS_XSLoader_load_file) {
163214 }
164215 PL_stack_sp -- ;
165216 if ((items = dl_load_file (aTHX_ ax , file , module , GIMME ))) {
217+ FREETMPS ; LEAVE ;
166218 XSRETURN (items );
167219 } else {
220+ FREETMPS ; LEAVE ;
168221 XSRETURN_UNDEF ;
169222 }
170223}
@@ -176,10 +229,14 @@ XS(XS_XSLoader_bootstrap_inherit) {
176229 SvPVX (ST (0 )), (int )items ));
177230 if (items < 1 || !SvPOK (ST (0 )))
178231 Perl_die (aTHX_ "Usage: XSLoader::bootstrap_inherit($packagename [,$VERSION])\n" );
232+ ENTER ; SAVETMPS ;
179233 PUSHMARK (MARK );
180234 PUTBACK ;
181- if ((items = call_pv ("DynaLoader::bootstrap_inherit" , GIMME )))
235+ if ((items = call_pv ("DynaLoader::bootstrap_inherit" , GIMME ))) {
236+ FREETMPS ; LEAVE ;
182237 XSRETURN (items );
183- else
238+ } else {
239+ FREETMPS ; LEAVE ;
184240 XSRETURN_UNDEF ;
241+ }
185242}
0 commit comments