Bugtraq mailing list archives

Re: Symlinks and Cryogenic Sleep


From: mheuse () KPMG COM (Marc Heuse)
Date: Wed, 5 Jan 2000 09:57:24 -0000


Hi,

when you're dealing with files in /tmp that are supposed to be re-opened
(rather than opened once and then discarded) there's an established
way to do it which goes like this:
[...]

I did something that way:

oh, not a good idea:

FILE *DoOpen(const char *cpFile, long bAppend)
{
  FILE *spNew;
  FILE *spTest;
  struct stat sStat;

  spTest = fopen(cpFile,"a");
  if (!spTest)
  {
     Log("ERR FILE OPEN",cpFile);
     return NULL;
  }

man fopen says about "a" (append mode):
the file is created, if it does not exist.
make cpFile a symlink to anything, and your function will create it (e.g. /etc/nologin).

  if (lstat(cpFile,&sStat))
  {
     Log("ERR STAT",cpFile);
     return NULL;
  }
  if ((sStat.st_mode & S_IFMT) == S_IFLNK)
  {
     fclose(spTest);
     Log("ERR ISLINK",cpFile);
     return NULL;
  }

now, if cpFile is a hardlink to e.g. /etc/passwd, this won´t help.
and even better: you´ve got the same race condition which Olaf describes, but the other way around. If the attacker 
creates the symlink before your fopen() call and before you do the lstat, he removes/renames it and creates a regular 
file, boom ...

  if (bAppend)
     spNew = spTest;
[... etc. the rest of the code is not relevant to security]

Comments ?
Improvements ?

well, it´s insecure... :-(
I also posted a reply some hours ago to bugtraq with my proposed algorythm to eliminate the race condition. I sent it 
from marc () suse de ... well, might take some time until it´s approved (but probably faster than this one ;-)

Greets,
        Marc

Please note that all statements here are my own opinions and do not reflect any point of view of the company where I 
work at...


Current thread: