diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2001-06-20 04:54:53 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2001-06-20 04:54:53 +0000 |
commit | cb5953d685cec7d1e5d677ac4d2ddbe33ef0a803 (patch) | |
tree | e9a08ee62f26a14c0e39ec84ea16f867ce892576 | |
parent | 6002328acc4eebf94540b6802dbffeac7367da7a (diff) | |
download | perl-cb5953d685cec7d1e5d677ac4d2ddbe33ef0a803.tar.gz |
After some reading I don't think we can blindly
use systems' realpath(). Too many security problems,
too many buggy implementations.
TODO: the realpath() emulation code in util.c doesn't
seem fully operational? (readlink(), for example?)
p4raw-id: //depot/perl@10744
-rwxr-xr-x | Configure | 8 | ||||
-rw-r--r-- | Makefile.micro | 2 | ||||
-rw-r--r-- | Porting/Glossary | 4 | ||||
-rw-r--r-- | Porting/config.sh | 13 | ||||
-rw-r--r-- | Porting/config_H | 14 | ||||
-rw-r--r-- | config_h.SH | 6 | ||||
-rwxr-xr-x | embed.pl | 2 | ||||
-rw-r--r-- | perlapi.c | 4 | ||||
-rw-r--r-- | pod/perldiag.pod | 6 | ||||
-rw-r--r-- | pod/perltoc.pod | 14 | ||||
-rw-r--r-- | uconfig.h | 8 | ||||
-rwxr-xr-x | uconfig.sh | 1 | ||||
-rw-r--r-- | util.c | 87 | ||||
-rw-r--r-- | vos/config.alpha.def | 1 | ||||
-rw-r--r-- | vos/config.alpha.h | 6 | ||||
-rw-r--r-- | vos/config.ga.def | 1 | ||||
-rw-r--r-- | vos/config.ga.h | 6 | ||||
-rw-r--r-- | win32/config_H.bc | 6 | ||||
-rw-r--r-- | win32/config_H.gc | 6 | ||||
-rw-r--r-- | win32/config_H.vc | 6 |
20 files changed, 71 insertions, 130 deletions
@@ -20,7 +20,7 @@ # $Id: Head.U,v 3.0.1.9 1997/02/28 15:02:09 ram Exp $ # -# Generated on Wed Jun 20 02:24:20 EET DST 2001 [metaconfig 3.0 PL70] +# Generated on Wed Jun 20 08:47:08 EET DST 2001 [metaconfig 3.0 PL70] # (with additional metaconfig patches by perlbug@perl.org) cat >c1$$ <<EOF @@ -485,7 +485,6 @@ d_seekdir='' d_telldir='' d_readlink='' d_readv='' -d_realpath='' d_recvmsg='' d_rename='' d_rmdir='' @@ -11407,10 +11406,6 @@ eval $inlibc set readv d_readv eval $inlibc -: see if realpath exists -set realpath d_realpath -eval $inlibc - : see if recvmsg exists set recvmsg d_recvmsg eval $inlibc @@ -16717,7 +16712,6 @@ d_quad='$d_quad' d_readdir='$d_readdir' d_readlink='$d_readlink' d_readv='$d_readv' -d_realpath='$d_realpath' d_recvmsg='$d_recvmsg' d_rename='$d_rename' d_rewinddir='$d_rewinddir' diff --git a/Makefile.micro b/Makefile.micro index 4ed2a1c907..78113aaad6 100644 --- a/Makefile.micro +++ b/Makefile.micro @@ -16,7 +16,7 @@ O = uav$(_O) udeb$(_O) udoio$(_O) udoop$(_O) udump$(_O) \ uregcomp$(_O) uregexec$(_O) urun$(_O) \ uscope$(_O) usv$(_O) utaint$(_O) utoke$(_O) \ unumeric$(_O) ulocale$(_O) \ - uuniversal$(_O) uutf8$(_O) uutil$(_O) uperlapi$(_O) \ + uuniversal$(_O) uutf8$(_O) uutil$(_O) uperlapi$(_O) microperl: $(O) $(LD) -o $@ $(O) $(LIBS) diff --git a/Porting/Glossary b/Porting/Glossary index 26e6e4ca92..fa87e63ffe 100644 --- a/Porting/Glossary +++ b/Porting/Glossary @@ -1258,10 +1258,6 @@ d_readv (d_readv.U): This variable conditionally defines the HAS_READV symbol, which indicates to the C program that the readv() routine is available. -d_realpath (d_realpath.U): - This variable conditionally defines the HAS_REALPATH symbol, which - indicates to the C program that the realpath() routine is available. - d_recvmsg (d_recvmsg.U): This variable conditionally defines the HAS_RECVMSG symbol, which indicates to the C program that the recvmsg() routine is available. diff --git a/Porting/config.sh b/Porting/config.sh index b804e9526b..5dc8a7e033 100644 --- a/Porting/config.sh +++ b/Porting/config.sh @@ -8,7 +8,7 @@ # Package name : perl5 # Source directory : . -# Configuration time: Fri Jun 15 02:15:37 EET DST 2001 +# Configuration time: Wed Jun 20 08:48:18 EET DST 2001 # Configured by : jhi # Target system : osf1 alpha.hut.fi v4.0 878 alpha @@ -63,7 +63,7 @@ ccsymbols='__alpha=1 __LANGUAGE_C__=1 __osf__=1 __unix__=1 _LONGLONG=1 _SYSTYPE_ ccversion='V5.6-082' cf_by='jhi' cf_email='yourname@yourhost.yourplace.com' -cf_time='Fri Jun 15 02:15:37 EET DST 2001' +cf_time='Wed Jun 20 08:48:18 EET DST 2001' charsize='1' chgrp='' chmod='' @@ -85,7 +85,7 @@ cppstdin='cppstdin' cppsymbols='_AES_SOURCE=1 __alpha=1 __ALPHA=1 _ANSI_C_SOURCE=1 __LANGUAGE_C__=1 _LONGLONG=1 __osf__=1 _OSF_SOURCE=1 _POSIX_C_SOURCE=199506 _POSIX_SOURCE=1 _REENTRANT=1 __STDC__=1 _SYSTYPE_BSD=1 __unix__=1 _XOPEN_SOURCE=1' cryptlib='' csh='csh' -d_Gconvert='gcvt((x),(n),(b))' +d_Gconvert='sprintf((b),"%.*g",(n),(x))' d_PRIEUldbl='define' d_PRIFUldbl='define' d_PRIGUldbl='define' @@ -287,7 +287,6 @@ d_quad='define' d_readdir='define' d_readlink='define' d_readv='define' -d_realpath='define' d_recvmsg='define' d_rename='define' d_rewinddir='define' @@ -438,7 +437,7 @@ eunicefix=':' exe_ext='' expr='expr' extensions='B ByteLoader Cwd DB_File Data/Dumper Devel/DProf Devel/Peek Digest/MD5 Encode Fcntl File/Glob Filter/Util/Call IO IPC/SysV List/Util MIME/Base64 NDBM_File ODBM_File Opcode POSIX PerlIO/Scalar PerlIO/Via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Thread Time/HiRes Time/Piece XS/Typemap attrs re Errno' -fflushNULL='undef' +fflushNULL='define' fflushall='undef' find='' firstmakefile='makefile' @@ -670,7 +669,7 @@ patchlevel='7' path_sep=':' perl5='/u/vieraat/vieraat/jhi/Perl/bin/perl' perl='' -perl_patchlevel='10575' +perl_patchlevel='10721' perladmin='yourname@yourhost.yourplace.com' perllibs='-lm -liconv -lutil -lpthread -lexc' perlpath='/opt/perl/bin/perl' @@ -870,7 +869,7 @@ PERL_SUBVERSION=1 PERL_API_REVISION=5 PERL_API_VERSION=5 PERL_API_SUBVERSION=0 -PERL_PATCHLEVEL=10575 +PERL_PATCHLEVEL=10721 PERL_CONFIG_SH=true # Variables propagated from previous config.sh file. pp_sys_cflags='ccflags="$ccflags -DNO_EFF_ONLY_OK"' diff --git a/Porting/config_H b/Porting/config_H index 9aea69c251..b2c523d3a3 100644 --- a/Porting/config_H +++ b/Porting/config_H @@ -17,7 +17,7 @@ /* * Package name : perl5 * Source directory : . - * Configuration time: Fri Jun 15 02:15:37 EET DST 2001 + * Configuration time: Wed Jun 20 08:48:18 EET DST 2001 * Configured by : jhi * Target system : osf1 alpha.hut.fi v4.0 878 alpha */ @@ -1019,7 +1019,7 @@ * 4 and 8. The default is eight, for safety. */ #if defined(USE_CROSS_COMPILE) || defined(MULTIARCH) -#define MEM_ALIGNBYTES 8 +# define MEM_ALIGNBYTES 8 #else #define MEM_ALIGNBYTES 8 #endif @@ -1362,7 +1362,7 @@ * d_Gconvert='sprintf((b),"%.*g",(n),(x))' * The last two assume trailing zeros should not be kept. */ -#define Gconvert(x,n,t,b) gcvt((x),(n),(b)) +#define Gconvert(x,n,t,b) sprintf((b),"%.*g",(n),(x)) /* HAS_GETCWD: * This symbol, if defined, indicates that the getcwd routine is @@ -2324,7 +2324,7 @@ * Note that if fflushNULL is defined, fflushall will not * even be probed for and will be left undefined. */ -/*#define FFLUSH_NULL / **/ +#define FFLUSH_NULL /**/ /*#define FFLUSH_ALL / **/ /* Fpos_t: @@ -3372,12 +3372,6 @@ */ /*#define HAS_FLOCK_PROTO / **/ -/* HAS_REALPATH: - * This symbol, if defined, indicates that the realpath routine is - * available to do resolve paths. - */ -#define HAS_REALPATH /**/ - /* HAS_SIGPROCMASK: * This symbol, if defined, indicates that the sigprocmask * system call is available to examine or change the signal mask diff --git a/config_h.SH b/config_h.SH index 35bfb1b1b7..235369c4dc 100644 --- a/config_h.SH +++ b/config_h.SH @@ -3392,12 +3392,6 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un */ #$d_flockproto HAS_FLOCK_PROTO /**/ -/* HAS_REALPATH: - * This symbol, if defined, indicates that the realpath routine is - * available to do resolve paths. - */ -#$d_realpath HAS_REALPATH /**/ - /* HAS_SIGPROCMASK: * This symbol, if defined, indicates that the sigprocmask * system call is available to examine or change the signal mask @@ -2058,7 +2058,7 @@ Apd |void |sv_pos_b2u |SV* sv|I32* offsetp Aopd |char* |sv_pvn_force |SV* sv|STRLEN* lp Apd |char* |sv_pvutf8n_force|SV* sv|STRLEN* lp Apd |char* |sv_pvbyten_force|SV* sv|STRLEN* lp -Apd |int |sv_realpath |SV* sv|char *path|STRLEN len +Apd |int |sv_realpath |SV* sv|char *path|STRLEN maxlen Apd |char* |sv_reftype |SV* sv|int ob Apd |void |sv_replace |SV* sv|SV* nsv Apd |void |sv_report_used @@ -3172,9 +3172,9 @@ Perl_sv_pvbyten_force(pTHXo_ SV* sv, STRLEN* lp) #undef Perl_sv_realpath int -Perl_sv_realpath(pTHXo_ SV* sv, char *path, STRLEN len) +Perl_sv_realpath(pTHXo_ SV* sv, char *path, STRLEN maxlen) { - return ((CPerlObj*)pPerl)->Perl_sv_realpath(sv, path, len); + return ((CPerlObj*)pPerl)->Perl_sv_realpath(sv, path, maxlen); } #undef Perl_sv_reftype diff --git a/pod/perldiag.pod b/pod/perldiag.pod index de8956be94..75f9ec08a1 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -3286,6 +3286,12 @@ assignment or as a subroutine argument for example). (F) Your Perl was compiled with B<-D>SETUID_SCRIPTS_ARE_SECURE_NOW, but a version of the setuid emulator somehow got run anyway. +=item sv_realpath: %s + +(S) You probably used some form of getcwd. The implementation of +that functionality detected something odd in your filesystem +environment and gave up (returning undef). + =item Switch (?(condition)... contains too many branches in regex; marked by <-- HERE in m/%s/ diff --git a/pod/perltoc.pod b/pod/perltoc.pod index 1094d8c92d..0912724c6b 100644 --- a/pod/perltoc.pod +++ b/pod/perltoc.pod @@ -3908,7 +3908,7 @@ PUSHn, PUSHp, PUSHs, PUSHu, PUTBACK, Renew, Renewc, require_pv, RETVAL, Safefree, savepv, savepvn, SAVETMPS, SP, SPAGAIN, ST, strEQ, strGE, strGT, strLE, strLT, strNE, strnEQ, strnNE, StructCopy, SvCUR, SvCUR_set, SvEND, SvGETMAGIC, SvGROW, SvIOK, SvIOKp, SvIOK_notUV, SvIOK_off, SvIOK_on, -SvIOK_only, SvIOK_only_UV, SvIOK_UV, SvIV, SvIVx, SvIVX, SvLEN, SvNIOK, +SvIOK_only, SvIOK_only_UV, SvIOK_UV, SvIV, SvIVX, SvIVx, SvLEN, SvNIOK, SvNIOKp, SvNIOK_off, SvNOK, SvNOKp, SvNOK_off, SvNOK_on, SvNOK_only, SvNV, SvNVx, SvNVX, SvOK, SvOOK, SvPOK, SvPOKp, SvPOK_off, SvPOK_on, SvPOK_only, SvPOK_only_UTF8, SvPV, SvPVbyte, SvPVbytex, SvPVbytex_force, @@ -4575,22 +4575,26 @@ I<The Road goes ever on and on, down from the door where it began.> =item Incompatible Changes +=over 4 + +=item 64-bit platforms and malloc + =item Future Deprecations +=back + =item Core Enhancements =item Modules and Pragmata =over 4 -=item New Modules +=item New Modules and Distribution =item Updated And Improved Modules and Pragmata =back -=item Performance Enhancements - =item Utility Changes =item New Documentation @@ -4651,6 +4655,8 @@ I<The Road goes ever on and on, down from the door where it began.> =item Self-tying of Arrays and Hashes Is Forbidden +=item Variable Attributes are not Currently Usable for Tieing + =item Building Extensions Can Fail Because Of Largefiles =item The Compiler Suite Is Still Experimental @@ -1015,7 +1015,7 @@ * 4 and 8. The default is eight, for safety. */ #if defined(USE_CROSS_COMPILE) || defined(MULTIARCH) -#define MEM_ALIGNBYTES 8 +# define MEM_ALIGNBYTES 8 #else #define MEM_ALIGNBYTES 4 #endif @@ -3368,12 +3368,6 @@ */ /*#define HAS_FLOCK_PROTO / **/ -/* HAS_REALPATH: - * This symbol, if defined, indicates that the realpath routine is - * available to do resolve paths. - */ -/*#define HAS_REALPATH / **/ - /* HAS_SIGPROCMASK: * This symbol, if defined, indicates that the sigprocmask * system call is available to examine or change the signal mask diff --git a/uconfig.sh b/uconfig.sh index 52e34b7b75..ca35351d25 100755 --- a/uconfig.sh +++ b/uconfig.sh @@ -218,7 +218,6 @@ d_quad='undef' d_readdir='undef' d_readlink='undef' d_readv='undef' -d_realpath='undef' d_recvmsg='undef' d_rename='undef' d_rewinddir='undef' @@ -3624,6 +3624,9 @@ Perl_sv_getcwd(pTHX_ register SV *sv) SvGROW(sv, 128); while ((getcwd(SvPVX(sv), SvLEN(sv)-1) == NULL) && errno == ERANGE) { + if (SvLEN(sv) + 128 >= MAXPATHLEN) { + SV_CWD_RETURN_UNDEF; + } SvGROW(sv, SvLEN(sv) + 128); } SvCUR_set(sv, strlen(SvPVX(sv))); @@ -3687,6 +3690,10 @@ Perl_sv_getcwd(pTHX_ register SV *sv) SV_CWD_RETURN_UNDEF; } + if (pathlen + namelen + 1 >= MAXPATHLEN) { + SV_CWD_RETURN_UNDEF; + } + SvGROW(sv, pathlen + namelen + 1); if (pathlen) { @@ -3737,62 +3744,44 @@ Perl_sv_getcwd(pTHX_ register SV *sv) /* =for apidoc sv_realpath -Wrap or emulate realpath(3). +Emulate realpath(3). + +The real realpath() is not used because it's a known can of worms. +We may have bugs but hey, they are our very own. =cut */ int -Perl_sv_realpath(pTHX_ SV *sv, char *path, STRLEN len) +Perl_sv_realpath(pTHX_ SV *sv, char *path, STRLEN maxlen) { #ifndef PERL_MICRO - char name[MAXPATHLEN] = { 0 }, *s; + char name[MAXPATHLEN] = { 0 }; + char dotdots[MAXPATHLEN] = { 0 }; + char *s; STRLEN pathlen, namelen; + DIR *parent; + Direntry_t *dp; + struct stat cst, pst, tst; - /* Don't use strlen() to avoid running off the end. */ - s = memchr(path, '\0', MAXPATHLEN); - pathlen = s ? s - path : MAXPATHLEN; - -#ifdef HAS_REALPATH - - /* Be paranoid about the use of realpath(), - * it is an infamous source of buffer overruns. */ - - /* Is the source buffer too long? */ - if (pathlen == MAXPATHLEN) { - Perl_warn(aTHX_ "sv_realpath: realpath(\"%s\"): %c= (MAXPATHLEN = %d)", - path, s ? '=' : '>', MAXPATHLEN); - SV_CWD_RETURN_UNDEF; - } - - /* Here goes nothing. */ - if (realpath(path, name) == NULL) { - Perl_warn(aTHX_ "sv_realpath: realpath(\"%s\"): %s", - path, Strerror(errno)); + if (!sv || !path || !maxlen) { + Perl_warn(aTHX_ "sv_realpath: realpath(0x%x, 0x%x, "")", + sv, path, maxlen); SV_CWD_RETURN_UNDEF; } - /* Is the destination buffer too long? + /* Is the source buffer too long? * Don't use strlen() to avoid running off the end. */ - s = memchr(name, '\0', MAXPATHLEN); - namelen = s ? s - name : MAXPATHLEN; - if (namelen == MAXPATHLEN) { - Perl_warn(aTHX_ "sv_realpath: realpath(\"%s\"): %c= (MAXPATHLEN = %d)", - path, s ? '=' : '>', MAXPATHLEN); + if (maxlen >= MAXPATHLEN) + pathlen = maxlen; + else { + s = memchr(path, '\0', MAXPATHLEN); + pathlen = s ? s - path : MAXPATHLEN; + } + if (pathlen >= MAXPATHLEN) { + Perl_warn(aTHX_ "sv_realpath: source too large"); SV_CWD_RETURN_UNDEF; } - /* The coast is clear? */ - sv_setpvn(sv, name, namelen); - SvPOK_only(sv); - - return TRUE; -#else - { - DIR *parent; - Direntry_t *dp; - char dotdots[MAXPATHLEN] = { 0 }; - struct stat cst, pst, tst; - if (PerlLIO_stat(path, &cst) < 0) { Perl_warn(aTHX_ "sv_realpath: stat(\"%s\"): %s", path, Strerror(errno)); @@ -3801,10 +3790,9 @@ Perl_sv_realpath(pTHX_ SV *sv, char *path, STRLEN len) (void)SvUPGRADE(sv, SVt_PV); - if (!len) { - len = strlen(path); - } - Copy(path, dotdots, len, char); + Copy(path, dotdots, maxlen, char); + + pathlen = 0; for (;;) { strcat(dotdots, "/.."); @@ -3864,6 +3852,11 @@ Perl_sv_realpath(pTHX_ SV *sv, char *path, STRLEN len) SV_CWD_RETURN_UNDEF; } + if (pathlen + namelen + 1 >= MAXPATHLEN) { + Perl_warn(aTHX_ "sv_realpath: too long name"); + SV_CWD_RETURN_UNDEF; + } + SvGROW(sv, pathlen + namelen + 1); if (pathlen) { /* shift down */ @@ -3890,10 +3883,8 @@ Perl_sv_realpath(pTHX_ SV *sv, char *path, STRLEN len) SvPOK_only(sv); return TRUE; - } -#endif #else - return FALSE; + return FALSE; /* MICROPERL */ #endif } diff --git a/vos/config.alpha.def b/vos/config.alpha.def index 23196501c3..006551691c 100644 --- a/vos/config.alpha.def +++ b/vos/config.alpha.def @@ -194,7 +194,6 @@ $d_quad='undef' $d_readdir='define' $d_readlink='define' $d_readv='undef' -$d_realpath='undef' $d_recvmsg='undef' $d_rename='define' $d_rewinddir='define' diff --git a/vos/config.alpha.h b/vos/config.alpha.h index 54dfc0c7fe..3f47acfcd0 100644 --- a/vos/config.alpha.h +++ b/vos/config.alpha.h @@ -3368,12 +3368,6 @@ */ /*#define HAS_FLOCK_PROTO /**/ -/* HAS_REALPATH: - * This symbol, if defined, indicates that the realpath routine is - * available to do resolve paths. - */ -/*#define HAS_REALPATH /**/ - /* HAS_SIGPROCMASK: * This symbol, if defined, indicates that the sigprocmask * system call is available to examine or change the signal mask diff --git a/vos/config.ga.def b/vos/config.ga.def index 9a0a02cf98..4d49cf53ad 100644 --- a/vos/config.ga.def +++ b/vos/config.ga.def @@ -194,7 +194,6 @@ $d_quad='undef' $d_readdir='define' $d_readlink='define' $d_readv='undef' -$d_realpath='undef' $d_recvmsg='undef' $d_rename='define' $d_rewinddir='define' diff --git a/vos/config.ga.h b/vos/config.ga.h index 8c4dd35376..5b283e3f13 100644 --- a/vos/config.ga.h +++ b/vos/config.ga.h @@ -3368,12 +3368,6 @@ */ /*#define HAS_FLOCK_PROTO /**/ -/* HAS_REALPATH: - * This symbol, if defined, indicates that the realpath routine is - * available to do resolve paths. - */ -/*#define HAS_REALPATH /**/ - /* HAS_SIGPROCMASK: * This symbol, if defined, indicates that the sigprocmask * system call is available to examine or change the signal mask diff --git a/win32/config_H.bc b/win32/config_H.bc index 6efd9cac9a..6f1d3c1914 100644 --- a/win32/config_H.bc +++ b/win32/config_H.bc @@ -3368,12 +3368,6 @@ */ /*#define HAS_FLOCK_PROTO /**/ -/* HAS_REALPATH: - * This symbol, if defined, indicates that the realpath routine is - * available to do resolve paths. - */ -/*#define HAS_REALPATH /**/ - /* HAS_SIGPROCMASK: * This symbol, if defined, indicates that the sigprocmask * system call is available to examine or change the signal mask diff --git a/win32/config_H.gc b/win32/config_H.gc index 0f20bce9c2..ce85240be0 100644 --- a/win32/config_H.gc +++ b/win32/config_H.gc @@ -3368,12 +3368,6 @@ */ /*#define HAS_FLOCK_PROTO /**/ -/* HAS_REALPATH: - * This symbol, if defined, indicates that the realpath routine is - * available to do resolve paths. - */ -/*#define HAS_REALPATH /**/ - /* HAS_SIGPROCMASK: * This symbol, if defined, indicates that the sigprocmask * system call is available to examine or change the signal mask diff --git a/win32/config_H.vc b/win32/config_H.vc index 476245ea42..e48c157707 100644 --- a/win32/config_H.vc +++ b/win32/config_H.vc @@ -3368,12 +3368,6 @@ */ /*#define HAS_FLOCK_PROTO /**/ -/* HAS_REALPATH: - * This symbol, if defined, indicates that the realpath routine is - * available to do resolve paths. - */ -/*#define HAS_REALPATH /**/ - /* HAS_SIGPROCMASK: * This symbol, if defined, indicates that the sigprocmask * system call is available to examine or change the signal mask |