prototype of Perl_moreswitches.
p4raw-id: //depot/perl@27070
Ap |void |mini_mktime |NN struct tm *pm
p |OP* |mod |NULLOK OP* o|I32 type
p |int |mode_from_discipline|NULLOK SV* discp
-Ap |char* |moreswitches |NN char* s
+Ap |char* |moreswitches |NN char* s|int suidscript
p |OP* |my |NN OP* o
Ap |NV |my_atof |NN const char *s
#if (!defined(HAS_MEMCPY) && !defined(HAS_BCOPY)) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY) && !defined(HAS_SAFE_BCOPY))
#endif
#if defined(PERL_IN_PERL_C) || defined(PERL_DECL_PROT)
-s |void |find_beginning
-s |void |forbid_setid |char flag
+s |void |find_beginning |int suidscript
+s |void |forbid_setid |char flag|int suidscript
s |void |incpush |NULLOK const char *dir|bool addsubdirs|bool addoldvers|bool usesep|bool canrelocate
s |void |init_interp
s |void |init_ids
s |void |init_predump_symbols
rs |void |my_exit_jump
s |void |nuke_stacks
-s |int |open_script |NN const char *scriptname|bool dosearch|NN SV *sv
+s |int |open_script |NN const char *scriptname|bool dosearch \
+ |NN SV *sv|NN int *suidscript
s |void |usage |NN const char *name
s |void |validate_suid |NN const char *validarg \
- |NN const char *scriptname|int fdscript
+ |NN const char *scriptname|int fdscript \
+ |int suidscript
# if defined(IAMSUID)
s |int |fd_on_nosuid_fs|int fd
# endif
#define mod(a,b) Perl_mod(aTHX_ a,b)
#define mode_from_discipline(a) Perl_mode_from_discipline(aTHX_ a)
#endif
-#define moreswitches(a) Perl_moreswitches(aTHX_ a)
+#define moreswitches(a,b) Perl_moreswitches(aTHX_ a,b)
#ifdef PERL_CORE
#define my(a) Perl_my(aTHX_ a)
#endif
#endif
#if defined(PERL_IN_PERL_C) || defined(PERL_DECL_PROT)
#ifdef PERL_CORE
-#define find_beginning() S_find_beginning(aTHX)
-#define forbid_setid(a) S_forbid_setid(aTHX_ a)
+#define find_beginning(a) S_find_beginning(aTHX_ a)
+#define forbid_setid(a,b) S_forbid_setid(aTHX_ a,b)
#define incpush(a,b,c,d,e) S_incpush(aTHX_ a,b,c,d,e)
#define init_interp() S_init_interp(aTHX)
#define init_ids() S_init_ids(aTHX)
#define init_predump_symbols() S_init_predump_symbols(aTHX)
#define my_exit_jump() S_my_exit_jump(aTHX)
#define nuke_stacks() S_nuke_stacks(aTHX)
-#define open_script(a,b,c) S_open_script(aTHX_ a,b,c)
+#define open_script(a,b,c,d) S_open_script(aTHX_ a,b,c,d)
#define usage(a) S_usage(aTHX_ a)
-#define validate_suid(a,b,c) S_validate_suid(aTHX_ a,b,c)
+#define validate_suid(a,b,c,d) S_validate_suid(aTHX_ a,b,c,d)
#endif
# if defined(IAMSUID)
#ifdef PERL_CORE
#define PL_sublex_info (vTHX->Isublex_info)
#define PL_subline (vTHX->Isubline)
#define PL_subname (vTHX->Isubname)
-#define PL_suidscript (vTHX->Isuidscript)
#define PL_sv_arenaroot (vTHX->Isv_arenaroot)
#define PL_sv_count (vTHX->Isv_count)
#define PL_sv_no (vTHX->Isv_no)
#define PL_Isublex_info PL_sublex_info
#define PL_Isubline PL_subline
#define PL_Isubname PL_subname
-#define PL_Isuidscript PL_suidscript
#define PL_Isv_arenaroot PL_sv_arenaroot
#define PL_Isv_count PL_sv_count
#define PL_Isv_no PL_sv_no
PERLVARI(Irehash_seed_set, bool, FALSE) /* 582 hash initialized? */
-/* These two variables are needed to preserve 5.8.x bincompat because we can't
- change function prototypes of two exported functions. Probably should be
- taken out of blead soon, and relevant prototypes changed. */
-PERLVARI(Isuidscript, int, -1) /* fd for suid script */
#ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
/* File descriptor to talk to the child which dumps scalars. */
PERLVARI(Idumper_fd, int, -1)
bool minus_f = FALSE;
#endif
int fdscript;
+ int suidscript;
- PL_suidscript = -1;
sv_setpvn(PL_linestr,"",0);
sv = newSVpvs(""); /* first used for -I flags */
SAVEFREESV(sv);
case 'X':
case 'w':
case 'A':
- if ((s = moreswitches(s)))
+ if ((s = moreswitches(s, suidscript)))
goto reswitch;
break;
if (argv[1] && !strcmp(argv[1], "Dev:Pseudo"))
break;
#endif
- forbid_setid('e');
+ forbid_setid('e', suidscript);
if (!PL_e_script) {
PL_e_script = newSVpvs("");
filter_add(read_e_script, NULL);
goto reswitch;
case 'I': /* -I handled both here and in moreswitches() */
- forbid_setid('I');
+ forbid_setid('I', suidscript);
if (!*++s && (s=argv[1]) != NULL) {
argc--,argv++;
}
Perl_croak(aTHX_ "No directory specified for -I");
break;
case 'P':
- forbid_setid('P');
+ forbid_setid('P', suidscript);
PL_preprocess = TRUE;
s++;
goto reswitch;
case 'S':
- forbid_setid('S');
+ forbid_setid('S', suidscript);
dosearch = TRUE;
s++;
goto reswitch;
PL_tainting = TRUE;
}
} else {
- moreswitches(d);
+ moreswitches(d, suidscript);
}
}
}
else if (scriptname == NULL) {
#ifdef MSDOS
if ( PerlLIO_isatty(PerlIO_fileno(PerlIO_stdin())) )
- moreswitches("h");
+ moreswitches("h", suidscript);
#endif
scriptname = "-";
}
TAINT_NOT;
init_perllib();
- fdscript = open_script(scriptname,dosearch,sv);
+ fdscript = open_script(scriptname, dosearch, sv, &suidscript);
- validate_suid(validarg, scriptname, fdscript);
+ validate_suid(validarg, scriptname, fdscript, suidscript);
#ifndef PERL_MICRO
#if defined(SIGCHLD) || defined(SIGCLD)
#else
if (PL_doextract) {
#endif
- find_beginning();
+ find_beginning(suidscript);
if (cddir && PerlDir_chdir( (char *)cddir ) < 0)
Perl_croak(aTHX_ "Can't chdir to %s",cddir);
/* This routine handles any switches that can be given during run */
char *
-Perl_moreswitches(pTHX_ char *s)
+Perl_moreswitches(pTHX_ char *s, const int suidscript)
{
dVAR;
UV rschar;
s++;
return s;
case 'd':
- forbid_setid('d');
+ forbid_setid('d', suidscript);
s++;
/* -dt indicates to the debugger that threads will be used */
case 'D':
{
#ifdef DEBUGGING
- forbid_setid('D');
+ forbid_setid('D', suidscript);
s++;
PL_debug = get_debug_opts( (const char **)&s, 1) | DEBUG_TOP_FLAG;
#else /* !DEBUGGING */
}
return s;
case 'I': /* -I handled both here and in parse_body() */
- forbid_setid('I');
+ forbid_setid('I', suidscript);
++s;
while (*s && isSPACE(*s))
++s;
}
return s;
case 'A':
- forbid_setid('A');
+ forbid_setid('A', suidscript);
if (!PL_preambleav)
PL_preambleav = newAV();
s++;
return s;
}
case 'M':
- forbid_setid('M'); /* XXX ? */
+ forbid_setid('M', suidscript); /* XXX ? */
/* FALL THROUGH */
case 'm':
- forbid_setid('m'); /* XXX ? */
+ forbid_setid('m', suidscript); /* XXX ? */
if (*++s) {
char *start;
SV *sv;
s++;
return s;
case 's':
- forbid_setid('s');
+ forbid_setid('s', suidscript);
PL_doswitches = TRUE;
s++;
return s;
/* PSz 18 Nov 03 fdscript now global but do not change prototype */
STATIC int
-S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv)
+S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv,
+ int *suidscript)
{
#ifndef IAMSUID
const char *quote;
int fdscript = -1;
dVAR;
- PL_suidscript = -1;
+ *suidscript = -1;
if (PL_e_script) {
PL_origfilename = savepvs("-e");
* Is it a mistake to use a similar /dev/fd/ construct for
* suidperl?
*/
- PL_suidscript = 1;
+ *suidscript = 1;
/* PSz 20 Feb 04
* Be supersafe and do some sanity-checks.
* Still, can we be sure we got the right thing?
* perl with that fd as it has always done.
*/
}
- if (PL_suidscript != 1) {
+ if (*suidscript != 1) {
Perl_croak(aTHX_ "suidperl needs (suid) fd script\n");
}
#else /* IAMSUID */
SvREFCNT_dec(cpp);
}
else if (!*scriptname) {
- forbid_setid(0);
+ forbid_setid(0, *suidscript);
PL_rsfp = PerlIO_stdin();
}
else {
STATIC void
S_validate_suid(pTHX_ const char *validarg, const char *scriptname,
- int fdscript)
+ int fdscript, int suidscript)
{
dVAR;
#ifdef IAMSUID
const char *s_end;
#ifdef IAMSUID
- if (fdscript < 0 || PL_suidscript != 1)
+ if (fdscript < 0 || suidscript != 1)
Perl_croak(aTHX_ "Need (suid) fdscript in suidperl\n"); /* We already checked this */
/* PSz 11 Nov 03
* Since the script is opened by perl, not suidperl, some of these
#ifdef IAMSUID
else if (PL_preprocess) /* PSz 13 Nov 03 Caught elsewhere, useless(?!) here */
Perl_croak(aTHX_ "-P not allowed for setuid/setgid script\n");
- else if (fdscript < 0 || PL_suidscript != 1)
+ else if (fdscript < 0 || suidscript != 1)
/* PSz 13 Nov 03 Caught elsewhere, useless(?!) here */
Perl_croak(aTHX_ "(suid) fdscript needed in suidperl\n");
else {
}
STATIC void
-S_find_beginning(pTHX)
+S_find_beginning(pTHX_ const int suidscript)
{
dVAR;
register char *s;
/* skip forward in input to the real script? */
- forbid_setid('x');
+ forbid_setid('x', suidscript);
#ifdef MACOS_TRADITIONAL
/* Since the Mac OS does not honor #! arguments for us, we do it ourselves */
while (isDIGIT(s2[-1]) || s2[-1] == '-' || s2[-1] == '.'
|| s2[-1] == '_') s2--;
if (strnEQ(s2-4,"perl",4))
- while ((s = moreswitches(s)))
+ while ((s = moreswitches(s, suidscript)))
;
}
#ifdef MACOS_TRADITIONAL
"program input from stdin", which is substituted in place of '\0', which
could never be a command line flag. */
STATIC void
-S_forbid_setid(pTHX_ const char flag)
+S_forbid_setid(pTHX_ const char flag, const int suidscript)
{
dVAR;
char string[3] = "-x";
*
* Also see comments about root running a setuid script, elsewhere.
*/
- if (PL_suidscript >= 0)
+ if (suidscript >= 0)
Perl_croak(aTHX_ "No %s allowed with (suid) fdscript", message);
#ifdef IAMSUID
/* PSz 11 Nov 03 Catch it in suidperl, always! */
#define PL_subline (*Perl_Isubline_ptr(aTHX))
#undef PL_subname
#define PL_subname (*Perl_Isubname_ptr(aTHX))
-#undef PL_suidscript
-#define PL_suidscript (*Perl_Isuidscript_ptr(aTHX))
#undef PL_sv_arenaroot
#define PL_sv_arenaroot (*Perl_Isv_arenaroot_ptr(aTHX))
#undef PL_sv_count
PERL_CALLCONV OP* Perl_mod(pTHX_ OP* o, I32 type);
PERL_CALLCONV int Perl_mode_from_discipline(pTHX_ SV* discp);
-PERL_CALLCONV char* Perl_moreswitches(pTHX_ char* s)
+PERL_CALLCONV char* Perl_moreswitches(pTHX_ char* s, int suidscript)
__attribute__nonnull__(pTHX_1);
PERL_CALLCONV OP* Perl_my(pTHX_ OP* o)
#endif
#if defined(PERL_IN_PERL_C) || defined(PERL_DECL_PROT)
-STATIC void S_find_beginning(pTHX);
-STATIC void S_forbid_setid(pTHX_ char flag);
+STATIC void S_find_beginning(pTHX_ int suidscript);
+STATIC void S_forbid_setid(pTHX_ char flag, int suidscript);
STATIC void S_incpush(pTHX_ const char *dir, bool addsubdirs, bool addoldvers, bool usesep, bool canrelocate);
STATIC void S_init_interp(pTHX);
STATIC void S_init_ids(pTHX);
__attribute__noreturn__;
STATIC void S_nuke_stacks(pTHX);
-STATIC int S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv)
+STATIC int S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv, int *suidscript)
__attribute__nonnull__(pTHX_1)
- __attribute__nonnull__(pTHX_3);
+ __attribute__nonnull__(pTHX_3)
+ __attribute__nonnull__(pTHX_4);
STATIC void S_usage(pTHX_ const char *name)
__attribute__nonnull__(pTHX_1);
-STATIC void S_validate_suid(pTHX_ const char *validarg, const char *scriptname, int fdscript)
+STATIC void S_validate_suid(pTHX_ const char *validarg, const char *scriptname, int fdscript, int suidscript)
__attribute__nonnull__(pTHX_1)
__attribute__nonnull__(pTHX_2);
Perl_croak(aTHX_ "Too late for \"-%.*s\" option",
(int)(d - m), m);
}
- d = moreswitches(d);
+ /* Given that these switches are within the script,
+ then it is not unsafe to allow them even within
+ a suidperl fd script. Hence pass in the
+ suidscript flag as -1, irrespective of what we
+ really are. */
+ d = moreswitches(d, -1);
} while (d);
if (PL_doswitches && !switches_done) {
int argc = PL_origargc;