Re: Perl's alleged tempfile vulnerabilities

From: Lupe Christoph (lupe@LUPE-CHRISTOPH.DE)
Date: Sun Feb 06 2000 - 01:35:17 PST

  • Next message: antirez: "Re: Tempfile vulnerabilities"

    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 |
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 15:33:40 PDT