[13734] in bugtraq
Re: Perl's alleged tempfile vulnerabilities
daemon@ATHENA.MIT.EDU (Lupe Christoph)
Mon Feb 7 17:23:54 2000
Mail-Followup-To: Tom Christiansen <tchrist@CHTHON.PERL.COM>,
BUGTRAQ@SECURITYFOCUS.COM
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Message-Id: <20000206103516.O12877@alanya.lupe-christoph.de>
Date: Sun, 6 Feb 2000 10:35:17 +0100
Reply-To: Lupe Christoph <lupe@LUPE-CHRISTOPH.DE>
From: Lupe Christoph <lupe@LUPE-CHRISTOPH.DE>
X-To: Tom Christiansen <tchrist@CHTHON.PERL.COM>
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To: <24194.949672117@chthon>; from tchrist@CHTHON.PERL.COM on Fri,
Feb 04, 2000 at 06:48:37AM -0700
On Friday, 2000-02-04 at 06:48:37 -0700, Tom Christiansen wrote:
> ...
> CODE:
> #ifdef PerlIO
> fp = PerlIO_tmpfile();
> #else
> fp = tmpfile();
> #endif
> ...
> Which is just calling the standard POSIX tmpfile() function. Well,
> sometimes. If you use the Perl I/O abstraction, then you get either
> the real tmpfile(), or under sfio, some sftmp(0) thingie that I
> know nothing about. The only hole I see is in my ignorance of the
> possible sfio-related sftmp(0) call. Enlightenment in this area
> is welcome.
--- Also sprach Tom Christiansen ---
Both sfio97 and sfio98 have (except for one teensy change) the same
sftmp.c. sftmp.c has this file creation code:
file = NIL(char*); fd = -1;
for(t = 0; t < 10; ++t)
{ /* compute a random name */
#if !_PACKAGE_ast
static ulong Key, A;
if(A == 0 || t > 0) /* get a quasi-random coefficient */
{ reg int r;
A = (ulong)time(NIL(time_t*)) ^ (((ulong)(&t)) >> 3);
if(Key == 0)
Key = (A >> 16) | ((A&0xffff)<<16);
A ^= Key;
if((r = (A-1) & 03) != 0) /* Knuth vol.2, page.16, Thm.A */
A += 4-r;
}
Key = A*Key + 987654321;
file = sfprints("%s/sf%3.3.32lu.%3.3.32lu",
Tmpcur[0], (Key>>15)&0x7fff, Key&0x7fff);
#else
file = pathtmp(file,NiL,"sf",NiL);
#endif /*!_PACKAGE_ast*/
if(!file)
return -1;
#if _has_oflags
if((fd = open(file,O_RDWR|O_CREAT|O_EXCL|O_TEMPORARY,SF_CREATMODE)) >= 0)
break;
#else
if((fd = open(file,O_RDONLY)) >= 0)
{ /* file already exists */
CLOSE(fd);
fd = -1;
}
else if((fd = creat(file,SF_CREATMODE)) >= 0)
{ /* reopen for read and write */
CLOSE(fd);
if((fd = open(file,O_RDWR)) >= 0)
break;
/* don't know what happened but must remove file */
while(remove(file) < 0 && errno == EINTR)
errno = 0;
}
#endif
}
if(fd >= 0)
_rmtmp(f, file);
I suppose ast is a Win32 matter *I* know nothing about.
So sfio goes to some length to randomize the filename, and then insists
on creating a new file. The randomization seems to be reasonably safe
from denial of service. sftmp can also use TMPPATH and TMPDIR.
sftmp will remove the file (_rmtmp) immediately unless _tmp_rmfail is
defined. I found no #define for that in the sfio98 code. (?)
Lupe Christoph
--
| lupe@lupe-christoph.de | http://free.prohosting.com/~lupe |
| "jryy vg ybbxf yvxr gur l2x oht qvqa'g erne vg'f htyl urnq." "lrc. gur |
| qbbzfnlref unir orra cebira jebat lrg ntnva." .... "qvq lbh frr gung |
| gbb?" "ubhfgba. jr unir n ceboyrz." User Friendly 2000-01-01 |