diff options
author | Nicholas Clark <nick@ccl4.org> | 2004-04-20 14:43:18 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2004-04-20 14:43:18 +0000 |
commit | 707d38420c0aa304635c36abea7b0b136d63cfcd (patch) | |
tree | a64e4a7a44c24d3ee8a87e0a38f457831aad6f50 | |
parent | 33fae54deded526e94a53b7d5a5e86c27b5996cb (diff) | |
download | perl-707d38420c0aa304635c36abea7b0b136d63cfcd.tar.gz |
Revert 22700 (as part of changes suggested by Brendan O'Dea)
p4raw-id: //depot/maint-5.8/perl@22718
-rw-r--r-- | INSTALL | 17 | ||||
-rwxr-xr-x | installperl | 4 | ||||
-rw-r--r-- | perl.c | 97 | ||||
-rw-r--r-- | pod/perl584delta.pod | 12 | ||||
-rw-r--r-- | pod/perldiag.pod | 18 | ||||
-rw-r--r-- | pod/perlsec.pod | 4 |
6 files changed, 72 insertions, 80 deletions
@@ -1504,9 +1504,9 @@ library installed for the Compress::Zlib, or the Foo database specific headers and libraries installed for the DBD::Foo module. The Configure process or the Perl build process will not help you with these. -=head1 setuidperl +=head1 suidperl -setuidperl is an optional component, which is built or installed by default. +suidperl is an optional component, which is built or installed by default. From perlfaq1: On some systems, setuid and setgid scripts (scripts written @@ -1514,13 +1514,13 @@ From perlfaq1: set user or group ID permissions enabled) are insecure due to a race condition in the kernel. For those systems, Perl versions 5 and 4 attempt to work around this vulnerability with an optional - component, a special program named setuidperl, also known as sperl. + component, a special program named suidperl, also known as sperl. This program attempts to emulate the set-user-ID and set-group-ID features of the kernel. -Because of the buggy history of setuidperl, and the difficulty +Because of the buggy history of suidperl, and the difficulty of properly security auditing as large and complex piece of -software as Perl, we cannot recommend using setuidperl and the feature +software as Perl, we cannot recommend using suidperl and the feature should be considered deprecated. Instead use for example 'sudo': http://www.courtesan.com/sudo/ @@ -2137,11 +2137,8 @@ make install will install the following: perl, perl5.nnn where nnn is the current release number. This will be a link to perl. - setuidperl5.nnn If you requested setuid emulation. - suidperl A link to perl, for backwards compatibility with setuid - scripts which expect to call the setuid emulation perl - directly. - sperl5.nnn A link to perl, for the same reasons as suidperl + suidperl, + sperl5.nnn If you requested setuid emulation. a2p awk-to-perl translator scripts diff --git a/installperl b/installperl index cadbb2698c..91cd722972 100755 --- a/installperl +++ b/installperl @@ -372,8 +372,8 @@ if ($d_dosuid) { # give it a different name for maintenance releases, as there are too many # entrenched scripts which call sperl directly. So the suid backend is # suidperl - copy("suidperl$exe_ext", "$installbin/setuid$perl_verbase$ver$exe_ext"); - chmod(04711, "$installbin/setuid$perl_verbase$ver$exe_ext"); + copy("suidperl$exe_ext", "$installbin/suid$perl_verbase$ver$exe_ext"); + chmod(04711, "$installbin/suid$perl_verbase$ver$exe_ext"); # and we provide a "sperl" which will keep on working the way these scripts # expect. link("$installbin/$perl_verbase$ver$exe_ext", @@ -25,17 +25,17 @@ * insecure: see perlsec(1) for many problems with this approach. * * The "correct" flow should be: perl starts, opens script and notices it is - * suid, checks many things, execs setuidperl with similar arguments but with - * script on /dev/fd/xxx; setuidperl checks script and /dev/fd/xxx object are + * suid, checks many things, execs suidperl with similar arguments but with + * script on /dev/fd/xxx; suidperl checks script and /dev/fd/xxx object are * same, checks arguments match #! line, sets itself with right UID, execs * perl with same arguments; perl checks many things and does work. * - * (Opening the script in perl instead of setuidperl, we "lose" scripts that + * (Opening the script in perl instead of suidperl, we "lose" scripts that * are readable to the target UID but not to the invoker. Where did * unreadable scripts work anyway?) * - * For now, setuidperl and perl are pretty much the same large and cumbersome - * program, so setuidperl can check its argument list (see comments elsewhere). + * For now, suidperl and perl are pretty much the same large and cumbersome + * program, so suidperl can check its argument list (see comments elsewhere). * * References: * Original bug report: @@ -1119,7 +1119,7 @@ perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env) #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW #ifdef IAMSUID #undef IAMSUID - Perl_croak(aTHX_ "setuidperl is no longer needed since the kernel can now execute\n\ + Perl_croak(aTHX_ "suidperl is no longer needed since the kernel can now execute\n\ setuid perl scripts securely.\n"); #endif /* IAMSUID */ #endif @@ -3074,10 +3074,10 @@ S_open_script(pTHX_ char *scriptname, bool dosearch, SV *sv) * Tell apart "normal" usage of fdscript, e.g. * with bash on FreeBSD: * perl <( echo '#!perl -DA'; echo 'print "$0\n"') - * from usage in setuidperl. + * from usage in suidperl. * Does any "normal" usage leave garbage after the number??? * Is it a mistake to use a similar /dev/fd/ construct for - * setuidperl? + * suidperl? */ PL_suidscript = 1; /* PSz 20 Feb 04 @@ -3111,18 +3111,18 @@ S_open_script(pTHX_ char *scriptname, bool dosearch, SV *sv) } #ifdef IAMSUID else { - Perl_croak(aTHX_ "setuidperl needs fd script\n" - "You should not call setuidperl directly; do you need to " - "change a #! line\nfrom setuidperl to perl?\n"); + Perl_croak(aTHX_ "suidperl needs fd script\n" + "You should not call suidperl directly; do you need to " + "change a #! line\nfrom suidperl to perl?\n"); /* PSz 11 Nov 03 * Do not open (or do other fancy stuff) while setuid. - * Perl does the open, and hands script to setuidperl on a fd; - * setuidperl only does some checks, sets up UIDs and re-execs + * Perl does the open, and hands script to suidperl on a fd; + * suidperl only does some checks, sets up UIDs and re-execs * perl with that fd as it has always done. */ } if (PL_suidscript != 1) { - Perl_croak(aTHX_ "setuidperl needs (suid) fd script\n"); + Perl_croak(aTHX_ "suidperl needs (suid) fd script\n"); } #else /* IAMSUID */ else if (PL_preprocess) { @@ -3366,17 +3366,16 @@ S_validate_suid(pTHX_ char *validarg, char *scriptname) * uid. We don't just make perl setuid root because that loses the * effective uid we had before invoking perl, if it was different from the * uid. - * PSz 27 Feb 04 * Description/comments above do not match current workings: - * setuidperl must be hardlinked to setuidperlN.NNN (that is what we exec); - * setuidperl called with script open and name changed to /dev/fd/N/X; - * setuidperl croaks if script is not setuid; + * suidperl must be hardlinked to suidperlN.NNN (that is what we exec); + * suidperl called with script open and name changed to /dev/fd/N/X; + * suidperl croaks if script is not setuid; * making perl setuid would be a huge security risk (and yes, that * would lose any euid we might have had). * - * DOSUID must be defined in both perl and setuidperl, and IAMSUID must - * be defined in setuidperl only. setuidperl must be setuid root. The + * DOSUID must be defined in both perl and suidperl, and IAMSUID must + * be defined in suidperl only. suidperl must be setuid root. The * Configure script will set this up for you if you want it. */ @@ -3391,11 +3390,11 @@ S_validate_suid(pTHX_ char *validarg, char *scriptname) #ifdef IAMSUID if (PL_fdscript < 0 || PL_suidscript != 1) { - Perl_croak(aTHX_ "Need (suid) fdscript in setuidperl\n"); + 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 setuidperl, some of these + * Since the script is opened by perl, not suidperl, some of these * checks are superfluous. Leaving them in probably does not lower * security(?!). */ @@ -3434,12 +3433,12 @@ S_validate_suid(pTHX_ char *validarg, char *scriptname) * Then we just have to make sure he or she can execute it. * * PSz 24 Feb 04 - * As the script is opened by perl, not setuidperl, we do not need to + * As the script is opened by perl, not suidperl, we do not need to * care much about access rights. * * The 'script changed' check is needed, or we can get lied to * about $0 with e.g. - * setuidperl /dev/fd/4//bin/x 4<setuidscript + * suidperl /dev/fd/4//bin/x 4<setuidscript * Without HAS_SETREUID, is it safe to stat() as root? * * Are there any operating systems that pass /dev/fd/xxx for setuid @@ -3508,8 +3507,8 @@ S_validate_suid(pTHX_ char *validarg, char *scriptname) while (*s == ' ' || *s == '\t') s++; /* * #! arg must be what we saw above. They can invoke it by - * mentioning setuidperl explicitly, but they may not add any strange - * arguments beyond what #! says if they do invoke setuidperl that way. + * mentioning suidperl explicitly, but they may not add any strange + * arguments beyond what #! says if they do invoke suidperl that way. */ /* * The way validarg was set up, we rely on the kernel to start @@ -3521,7 +3520,7 @@ S_validate_suid(pTHX_ char *validarg, char *scriptname) * just that there are no extraneous arguments). Might not matter * much, as switches from #! line seem to be acted upon (also), and * so may be checked and trapped in perl. But, security checks must - * be done in setuidperl and not deferred to perl. Note that setuidperl + * be done in suidperl and not deferred to perl. Note that suidperl * does not get around to parsing (and checking) the switches on * the #! line (but execs perl sooner). * Allow (require) a trailing newline (which may be of two @@ -3547,7 +3546,7 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n"); PL_euid) { /* oops, we're not the setuid root perl */ /* PSz 18 Feb 04 * When root runs a setuid script, we do not go through the same - * steps of execing setuidperl and then perl with fd scripts, but + * steps of execing suidperl and then perl with fd scripts, but * simply set up UIDs within the same perl invocation; so do * not have the same checks (on options, whatever) that we have * for plain users. No problem really: would have to be a script @@ -3562,8 +3561,8 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n"); #ifndef IAMSUID int which; /* PSz 11 Nov 03 - * Pass fd script to setuidperl. - * Exec setuidperl, substituting fd script for scriptname. + * Pass fd script to suidperl. + * Exec suidperl, substituting fd script for scriptname. * Pass script name as "subdir" of fd, which perl will grok; * in fact will use that to distinguish this from "normal" * usage, see comments above. @@ -3591,13 +3590,13 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n"); fcntl(PerlIO_fileno(PL_rsfp),F_SETFD,0); /* ensure no close-on-exec */ #endif PERL_FPU_PRE_EXEC - PerlProc_execv(Perl_form(aTHX_ "%s/setuidperl"PERL_FS_VER_FMT, + PerlProc_execv(Perl_form(aTHX_ "%s/suidperl"PERL_FS_VER_FMT, BIN_EXP, (int)PERL_REVISION, (int)PERL_VERSION, (int)PERL_SUBVERSION), PL_origargv); PERL_FPU_POST_EXEC #endif /* IAMSUID */ - Perl_croak(aTHX_ "Can't do setuid (cannot exec setuidperl)\n"); + Perl_croak(aTHX_ "Can't do setuid (cannot exec suidperl)\n"); } if (PL_statbuf.st_mode & S_ISGID && PL_statbuf.st_gid != PL_egid) { @@ -3667,10 +3666,10 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n"); Perl_croak(aTHX_ "-P not allowed for setuid/setgid script\n"); else if (PL_fdscript < 0 || PL_suidscript != 1) /* PSz 13 Nov 03 Caught elsewhere, useless(?!) here */ - Perl_croak(aTHX_ "(suid) fdscript needed in setuidperl\n"); + Perl_croak(aTHX_ "(suid) fdscript needed in suidperl\n"); else { /* PSz 16 Sep 03 Keep neat error message */ - Perl_croak(aTHX_ "Script is not setuid/setgid in setuidperl\n"); + Perl_croak(aTHX_ "Script is not setuid/setgid in suidperl\n"); } /* We absolutely must clear out any saved ids here, so we */ @@ -3682,34 +3681,34 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n"); * go on to "do the perl thing". * * Is there such a thing as "saved GID", and is that set for setuid (but - * not setgid) execution like setuidperl? Without exec, it would not be + * not setgid) execution like suidperl? Without exec, it would not be * cleared for setuid (but not setgid) scripts (or might need a dummy * setresgid). * - * We need setuidperl to do the exact same argument checking that perl + * We need suidperl to do the exact same argument checking that perl * does. Thus it cannot be very small; while it could be significantly * smaller, it is safer (simpler?) to make it essentially the same * binary as perl (but they are not identical). - Maybe could defer that - * check to the invoked perl, and setuidperl be a tiny wrapper instead; - * but prefer to do thorough checks in setuidperl itself. Such deferral - * would make setuidperl security rely on perl, a design no-no. + * check to the invoked perl, and suidperl be a tiny wrapper instead; + * but prefer to do thorough checks in suidperl itself. Such deferral + * would make suidperl security rely on perl, a design no-no. * * Setuid things should be short and simple, thus easy to understand and * verify. They should do their "own thing", without influence by * attackers. It may help if their internal execution flow is fixed, * regardless of platform: it may be best to exec anyway. * - * Setuidperl should at least be conceptually simple: a wrapper only, + * Suidperl should at least be conceptually simple: a wrapper only, * never to do any real perl. Maybe we should put * #ifdef IAMSUID - * Perl_croak(aTHX_ "Setuidperl should never do real perl\n"); + * Perl_croak(aTHX_ "Suidperl should never do real perl\n"); * #endif * into the perly bits. */ PerlIO_rewind(PL_rsfp); PerlLIO_lseek(PerlIO_fileno(PL_rsfp),(Off_t)0,0); /* just in case rewind didn't */ /* PSz 11 Nov 03 - * Keep original arguments: setuidperl already has fd script. + * Keep original arguments: suidperl already has fd script. */ /* for (which = 1; PL_origargv[which] && PL_origargv[which] != scriptname; which++) ; */ /* if (!PL_origargv[which]) { */ @@ -3726,10 +3725,10 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n"); (int)PERL_REVISION, (int)PERL_VERSION, (int)PERL_SUBVERSION), PL_origargv);/* try again */ PERL_FPU_POST_EXEC - Perl_croak(aTHX_ "Can't do setuid (setuidperl cannot exec perl)\n"); + Perl_croak(aTHX_ "Can't do setuid (suidperl cannot exec perl)\n"); #endif /* IAMSUID */ #else /* !DOSUID */ - if (PL_euid != PL_uid || PL_egid != PL_gid) { /* (setuidperl doesn't exist, in fact) */ + if (PL_euid != PL_uid || PL_egid != PL_gid) { /* (suidperl doesn't exist, in fact) */ #ifndef SETUID_SCRIPTS_ARE_SECURE_NOW PerlLIO_fstat(PerlIO_fileno(PL_rsfp),&PL_statbuf); /* may be either wrapped or real suid */ if ((PL_euid != PL_uid && PL_euid == PL_statbuf.st_uid && PL_statbuf.st_mode & S_ISUID) @@ -3891,7 +3890,7 @@ S_forbid_setid(pTHX_ char *s) * * This may be too late for command-line switches. Will catch those on * the #! line, after finding the script name and setting up - * fdscript/suidscript. Note that setuidperl does not get around to + * fdscript/suidscript. Note that suidperl does not get around to * parsing (and checking) the switches on the #! line, but checks that * the two sets are identical. * @@ -3899,8 +3898,8 @@ S_forbid_setid(pTHX_ char *s) * instead, or would that be "too late"? (We never have suidscript, can * we be sure to have fdscript?) * - * Catch things with suidscript (in descendant of setuidperl), even with - * right UID/GID. Was already checked in setuidperl, with #ifdef IAMSUID, + * Catch things with suidscript (in descendant of suidperl), even with + * right UID/GID. Was already checked in suidperl, with #ifdef IAMSUID, * below; but I am paranoid. * * Also see comments about root running a setuid script, elsewhere. @@ -3908,8 +3907,8 @@ S_forbid_setid(pTHX_ char *s) if (PL_suidscript >= 0) Perl_croak(aTHX_ "No %s allowed with (suid) fdscript", s); #ifdef IAMSUID - /* PSz 11 Nov 03 Catch it in setuidperl, always! */ - Perl_croak(aTHX_ "No %s allowed in setuidperl", s); + /* PSz 11 Nov 03 Catch it in suidperl, always! */ + Perl_croak(aTHX_ "No %s allowed in suidperl", s); #endif /* IAMSUID */ } diff --git a/pod/perl584delta.pod b/pod/perl584delta.pod index 97afdc3bf7..697225204a 100644 --- a/pod/perl584delta.pod +++ b/pod/perl584delta.pod @@ -25,6 +25,9 @@ such as newline and backspace are output in C<\x> notation, rather than octal. This might just confuse non-robust tools which parse the output of modules such as Devel::Peek. +You may no longer invoke suidperl directly; any script which uses +#!/usr/bin/suidperl should be changed to use #!/usr/bin/perl. + =head1 Core Enhancements =head2 Malloc wrapping @@ -48,14 +51,7 @@ been updated to 4.0.1 from 4.0.0. Paul Szabo has analysed and patched C<suidperl> to remove existing known insecurities. Currently there are no known holes in C<suidperl>, but previous experience shows that we cannot be confident that these were the -last. You may no longer invoke the set uid perl directly, so to preserve -backwards compatibility with scripts that invoke #!/usr/bin/suidperl -the set uid binary is now called C<setuidperl>, with C<suidperl> installed -as a hard link to C<perl>. Both C<suidperl> and C<perl> will invoke -C<setuidperl> automatically on a set uid script, so this change should be -completely transparent. - -For new projects the core perl team would strongly recommend that you +last. For new projects the core perl team would strongly recommend that you use dedicated, single purpose security tools such as C<sudo> in preference to C<suidperl>. diff --git a/pod/perldiag.pod b/pod/perldiag.pod index ab41f8e52e..9c2a0a5bd1 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -610,15 +610,15 @@ regular expression about where the problem was discovered. See L<perlre>. =item Can't do setegid! (P) The setegid() call failed for some reason in the setuid emulator of -setuidperl. +suidperl. =item Can't do seteuid! -(P) The setuid emulator of setuidperl failed for some reason. +(P) The setuid emulator of suidperl failed for some reason. =item Can't do setuid -(F) This typically means that ordinary perl tried to exec setuidperl to do +(F) This typically means that ordinary perl tried to exec suidperl to do setuid emulation, but couldn't exec it. It looks for a name of the form sperl5.000 in the same directory that the perl executable resides under the name perl5.000, typically /usr/local/bin on Unix machines. If the @@ -973,7 +973,7 @@ method name is C<???>, this is an internal error. =item Can't reswap uid and euid (P) The setreuid() call failed for some reason in the setuid emulator of -setuidperl. +suidperl. =item Can't return %s from lvalue subroutine @@ -1002,7 +1002,7 @@ open already. Bizarre. =item Can't swap uid and euid (P) The setreuid() call failed for some reason in the setuid emulator of -setuidperl. +suidperl. =item Can't take log of %g @@ -2914,7 +2914,7 @@ L<perllocale> section B<LOCALE PROBLEMS>. =item Permission denied -(F) The setuid emulator in setuidperl decided you were up to no good. +(F) The setuid emulator in suidperl decided you were up to no good. =item pid %x not a child @@ -3285,9 +3285,9 @@ as a list, you need to look into how references work, because Perl will not magically convert between scalars and lists for you. See L<perlref>. -=item Script is not setuid/setgid in setuidperl +=item Script is not setuid/setgid in suidperl -(F) Oddly, the setuidperl program was invoked on a script without a setuid +(F) Oddly, the suidperl program was invoked on a script without a setuid or setgid bit set. This doesn't make much sense. =item Search pattern not terminated @@ -3546,7 +3546,7 @@ length of the string. See L<perlfunc/substr>. This warning is fatal if substr is used in an lvalue context (as the left hand side of an assignment or as a subroutine argument for example). -=item setuidperl is no longer needed since %s +=item suidperl is no longer needed since %s (F) Your Perl was compiled with B<-D>SETUID_SCRIPTS_ARE_SECURE_NOW, but a version of the setuid emulator somehow got run anyway. diff --git a/pod/perlsec.pod b/pod/perlsec.pod index 3c41dba7e2..5a09e32d8e 100644 --- a/pod/perlsec.pod +++ b/pod/perlsec.pod @@ -330,7 +330,7 @@ outlaw scripts with any set-id bit set, which doesn't help much. Alternately, it can simply ignore the set-id bits on scripts. If the latter is true, Perl can emulate the setuid and setgid mechanism when it notices the otherwise useless setuid/gid bits on Perl scripts. It does -this via a special executable called B<setuidperl> that is automatically +this via a special executable called B<suidperl> that is automatically invoked for you if it's needed. However, if the kernel set-id script feature isn't disabled, Perl will @@ -362,7 +362,7 @@ program that builds Perl tries to figure this out for itself, so you should never have to specify this yourself. Most modern releases of SysVr4 and BSD 4.4 use this approach to avoid the kernel race condition. -Prior to release 5.6.1 of Perl, bugs in the code of B<setuidperl> could +Prior to release 5.6.1 of Perl, bugs in the code of B<suidperl> could introduce a security hole. =head2 Protecting Your Programs |