Bugtraq mailing list archives

Re: Perl's alleged tempfile vulnerabilities


From: lupe () LUPE-CHRISTOPH DE (Lupe Christoph)
Date: Sun, 6 Feb 2000 10:35:17 +0100


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 |



Current thread: