partial PL_statbuf removal

Perl_nextargv has to have access to the Stat_t that is written to inside
S_openn_cleanup or else run/switches.t, io/argv.t, io/inplace.t, and
io/iprefix.t will fail. Removing the uses of PL_statbuf that are using
PL_statbuf due to historical reason, and not using PL_statbuf to pass data
between different funcs/different callstacks. This patch makes it easier to
remove PL_statbuf in the future since the number uses of it has been
reduced.

-in Perl_apply move SETERRNO before tot--; so the branch can be combined
 with other "tot--;" branches by CC optmizer
-combine 2 Perl_croak(aTHX_ "Illegal suidscript"); statements in
 S_validate_suid to make code look simpler, drop my_perl arg for space
 efficiency on threads of rarely executed code
This commit is contained in:
Daniel Dragan 2015-08-14 18:34:09 -04:00 committed by David Mitchell
parent 0ee3fa26f6
commit 45a23732c7
5 changed files with 46 additions and 33 deletions

16
doio.c
View File

@ -835,6 +835,7 @@ Perl_nextargv(pTHX_ GV *gv, bool nomagicopen)
if (!GvAV(gv))
return NULL;
while (av_tindex(GvAV(gv)) >= 0) {
Stat_t statbuf;
STRLEN oldlen;
SV *const sv = av_shift(GvAV(gv));
SAVEFREESV(sv);
@ -976,13 +977,13 @@ Perl_nextargv(pTHX_ GV *gv, bool nomagicopen)
setdefout(PL_argvoutgv);
PL_lastfd = PerlIO_fileno(IoIFP(GvIOp(PL_argvoutgv)));
if (PL_lastfd >= 0) {
(void)PerlLIO_fstat(PL_lastfd,&PL_statbuf);
(void)PerlLIO_fstat(PL_lastfd,&statbuf);
#ifdef HAS_FCHMOD
(void)fchmod(PL_lastfd,PL_filemode);
#else
(void)PerlLIO_chmod(PL_oldname,PL_filemode);
#endif
if (fileuid != PL_statbuf.st_uid || filegid != PL_statbuf.st_gid) {
if (fileuid != statbuf.st_uid || filegid != statbuf.st_gid) {
/* XXX silently ignore failures */
#ifdef HAS_FCHOWN
PERL_UNUSED_RESULT(fchown(PL_lastfd,fileuid,filegid));
@ -999,8 +1000,8 @@ Perl_nextargv(pTHX_ GV *gv, bool nomagicopen)
if (ckWARN_d(WARN_INPLACE)) {
const int eno = errno;
if (PerlLIO_stat(PL_oldname, &PL_statbuf) >= 0
&& !S_ISREG(PL_statbuf.st_mode)) {
if (PerlLIO_stat(PL_oldname, &statbuf) >= 0
&& !S_ISREG(statbuf.st_mode)) {
Perl_warner(aTHX_ packWARN(WARN_INPLACE),
"Can't do inplace edit: %s is not a regular file",
PL_oldname);
@ -1934,11 +1935,12 @@ nothing in the core.
#endif
}
else { /* don't let root wipe out directories without -U */
if (PerlLIO_lstat(s,&PL_statbuf) < 0)
tot--;
else if (S_ISDIR(PL_statbuf.st_mode)) {
Stat_t statbuf;
if (PerlLIO_lstat(s, &statbuf) < 0)
tot--;
else if (S_ISDIR(statbuf.st_mode)) {
SETERRNO(EISDIR, SS_NOPRIV);
tot--;
}
else {
if (UNLINK(s))

13
perl.c
View File

@ -3840,16 +3840,13 @@ S_validate_suid(pTHX_ PerlIO *rsfp)
if (my_euid != my_uid || my_egid != my_gid) { /* (suidperl doesn't exist, in fact) */
dVAR;
int fd = PerlIO_fileno(rsfp);
if (fd < 0) {
Perl_croak(aTHX_ "Illegal suidscript");
} else {
if (PerlLIO_fstat(fd, &PL_statbuf) < 0) { /* may be either wrapped or real suid */
Perl_croak(aTHX_ "Illegal suidscript");
}
Stat_t statbuf;
if (fd < 0 || PerlLIO_fstat(fd, &statbuf) < 0) { /* may be either wrapped or real suid */
Perl_croak_nocontext( "Illegal suidscript");
}
if ((my_euid != my_uid && my_euid == PL_statbuf.st_uid && PL_statbuf.st_mode & S_ISUID)
if ((my_euid != my_uid && my_euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
||
(my_egid != my_gid && my_egid == PL_statbuf.st_gid && PL_statbuf.st_mode & S_ISGID)
(my_egid != my_gid && my_egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
)
if (!PL_do_undump)
Perl_croak(aTHX_ "YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\

View File

@ -1964,6 +1964,7 @@ Perl_do_readline(pTHX)
XPUSHs(sv);
if (type == OP_GLOB) {
const char *t1;
Stat_t statbuf;
if (SvCUR(sv) > 0 && SvCUR(PL_rs) > 0) {
char * const tmps = SvEND(sv) - 1;
@ -1979,7 +1980,7 @@ Perl_do_readline(pTHX)
if (strchr("$&*(){}[]'\";\\|?<>~`", *t1))
#endif
break;
if (*t1 && PerlLIO_lstat(SvPVX_const(sv), &PL_statbuf) < 0) {
if (*t1 && PerlLIO_lstat(SvPVX_const(sv), &statbuf) < 0) {
(void)POPs; /* Unmatched wildcard? Chuck it... */
continue;
}

View File

@ -3726,17 +3726,20 @@ PP(pp_rename)
{
dSP; dTARGET;
int anum;
#ifndef HAS_RENAME
Stat_t statbuf;
#endif
const char * const tmps2 = POPpconstx;
const char * const tmps = SvPV_nolen_const(TOPs);
TAINT_PROPER("rename");
#ifdef HAS_RENAME
anum = PerlLIO_rename(tmps, tmps2);
#else
if (!(anum = PerlLIO_stat(tmps, &PL_statbuf))) {
if (!(anum = PerlLIO_stat(tmps, &statbuf))) {
if (same_dirent(tmps2, tmps)) /* can always rename to same name */
anum = 1;
else {
if (PerlProc_geteuid() || PerlLIO_stat(tmps2, &PL_statbuf) < 0 || !S_ISDIR(PL_statbuf.st_mode))
if (PerlProc_geteuid() || PerlLIO_stat(tmps2, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode))
(void)UNLINK(tmps2);
if (!(anum = link(tmps, tmps2)))
anum = UNLINK(tmps);
@ -3898,7 +3901,8 @@ S_dooneliner(pTHX_ const char *cmd, const char *filename)
return 0;
}
else { /* some mkdirs return no failure indication */
anum = (PerlLIO_stat(save_filename, &PL_statbuf) >= 0);
Stat_t statbuf;
anum = (PerlLIO_stat(save_filename, &statbuf) >= 0);
if (PL_op->op_type == OP_RMDIR)
anum = !anum;
if (anum)

37
util.c
View File

@ -3281,13 +3281,16 @@ Perl_find_script(pTHX_ const char *scriptname, bool dosearch,
#endif
DEBUG_p(PerlIO_printf(Perl_debug_log,
"Looking for %s\n",cur));
if (PerlLIO_stat(cur,&PL_statbuf) >= 0
&& !S_ISDIR(PL_statbuf.st_mode)) {
dosearch = 0;
scriptname = cur;
{
Stat_t statbuf;
if (PerlLIO_stat(cur,&statbuf) >= 0
&& !S_ISDIR(statbuf.st_mode)) {
dosearch = 0;
scriptname = cur;
#ifdef SEARCH_EXTS
break;
break;
#endif
}
}
#ifdef SEARCH_EXTS
if (cur == scriptname) {
@ -3313,6 +3316,7 @@ Perl_find_script(pTHX_ const char *scriptname, bool dosearch,
bufend = s + strlen(s);
while (s < bufend) {
Stat_t statbuf;
# ifdef DOSISH
for (len = 0; *s
&& *s != ';'; len++, s++) {
@ -3349,8 +3353,8 @@ Perl_find_script(pTHX_ const char *scriptname, bool dosearch,
do {
#endif
DEBUG_p(PerlIO_printf(Perl_debug_log, "Looking for %s\n",tmpbuf));
retval = PerlLIO_stat(tmpbuf,&PL_statbuf);
if (S_ISDIR(PL_statbuf.st_mode)) {
retval = PerlLIO_stat(tmpbuf,&statbuf);
if (S_ISDIR(statbuf.st_mode)) {
retval = -1;
}
#ifdef SEARCH_EXTS
@ -3361,10 +3365,10 @@ Perl_find_script(pTHX_ const char *scriptname, bool dosearch,
#endif
if (retval < 0)
continue;
if (S_ISREG(PL_statbuf.st_mode)
&& cando(S_IRUSR,TRUE,&PL_statbuf)
if (S_ISREG(statbuf.st_mode)
&& cando(S_IRUSR,TRUE,&statbuf)
#if !defined(DOSISH)
&& cando(S_IXUSR,TRUE,&PL_statbuf)
&& cando(S_IXUSR,TRUE,&statbuf)
#endif
)
{
@ -3375,11 +3379,16 @@ Perl_find_script(pTHX_ const char *scriptname, bool dosearch,
xfailed = savepv(tmpbuf);
}
#ifndef DOSISH
if (!xfound && !seen_dot && !xfailed &&
(PerlLIO_stat(scriptname,&PL_statbuf) < 0
|| S_ISDIR(PL_statbuf.st_mode)))
{
Stat_t statbuf;
if (!xfound && !seen_dot && !xfailed &&
(PerlLIO_stat(scriptname,&statbuf) < 0
|| S_ISDIR(statbuf.st_mode)))
#endif
seen_dot = 1; /* Disable message. */
#ifndef DOSISH
}
#endif
seen_dot = 1; /* Disable message. */
if (!xfound) {
if (flags & 1) { /* do or die? */
/* diag_listed_as: Can't execute %s */