Ethereal-dev: Re: [ethereal-dev] Security race in ethereal leading to root access

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <guy@xxxxxxxxxx>
Date: Fri, 30 Jul 1999 11:02:48 -0700 (PDT)
> > Does anyone know how to fix this?  Perhaps we should call mkstemp and pass
> > a file descriptor to pcap instead?
> 
> It will be hard to pass pcap a file descriptor;

...but there's no requirement that we use "libpcap" to write the capture
file out; we could add that facility to "wiretap" instead, and use it
instead, and have "wiretap"s code to open an output file include a
routine that takes a file descriptor rather than a file name.

> mkstemp() would indeed give us a file guaranteed to be ours, and not
> linked to another file (/etc/passwd, e.g.).
> Glibc mkstemp(char*) modifies the character array that we pass it, so
> we do have access to the resulting random file name. Do all mkstemp()'s do
> this?

Solaris 2.5.1 appears to have a "mkstemp()" but doesn't document it! 
2.6, at least, documents it; its man page says

     The mkstemp() function replaces the contents of  the  string
     pointed  to by template by a unique file name, and returns a
     file descriptor for the file open for reading  and  writing.

Digital UNIX 4.0 also documents it, and its man page says:

  The mktemp() function replaces the contents of the string pointed to by the
  template parameter with a unique filename.  ...

  The mkstemp() function performs the same substitution to the template name
  ...

so it looks as they both replace the contents of the string.  The
Digital UNIX man page also says:

  Interfaces documented on this reference page conform to industry standards
  as follows:
 
  mktemp(), mkstemp():  XPG4-UNIX

The Single UNIX(R) Specification, Version 2 (which is XPG4 or is, or is
based on on its successor) says:

	The mkstemp() function replaces the contents of the string
	pointed to by template by a unique file name,

so I'd be inclined to say that any system that has a "mkstemp()" that
doesn't replace the contents of the buffer passed to it with the
resulting file name isn't worthy of being considered a UNIX.

> If we then have the filename, can we close our file descriptor, then
> pass the filename to pcap, can we be assured that nothing happened to that
> file that we created?

I'm not sure we can.  If we close the file descriptor, this is no
different from "mktemp()"; even if we *don't* close it, holding the file
open merely means that the file itself won't be removed - it doesn't
mean it won't be renamed, or that the link to it won't be removed, which
would allow another process to create some other file, e.g. a symlink to
"/etc/passwd", in its place.

> Can we chmod() that file while we have the file
> descriptor open so that only the user (root) can modify that file,

Not good enough - we need to prevent anybody other than the user from
modifying the link *to* the file.

On many UNIXes (probably most if not all modern UNIXes)

	1) the "sticky" bit on a directory keeps anybody other than the
	   owner of the file, the super-user, and perhaps the owner of
	   the directory from doing things with the names of files in
	   that directory;

	2) "/tmp" has the sticky bit set;

which should, I think, prevent anybody from exploiting that hole - but I
don't know whether we want to count on 1) and 2) being true.