Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Commit 35c912b

Browse files
author
Reini Urban
committed
XSLoader: allow relative file if in @inc
and add ENTER/LEAVE to for external callbacks and the main xs
1 parent 547b329 commit 35c912b

File tree

1 file changed

+68
-11
lines changed

1 file changed

+68
-11
lines changed

ext/DynaLoader/XSLoader.c

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)