bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#12632: file permissions checking mishandled when setuid


From: Paul Eggert
Subject: bug#12632: file permissions checking mishandled when setuid
Date: Tue, 23 Oct 2012 12:27:21 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:16.0) Gecko/20121016 Thunderbird/16.0.1

On 10/23/2012 09:44 AM, Eli Zaretskii wrote:
> Others, like "//.", are downright dangerous, because "\\.\" begins a
> device name on Windows.  With these arcana notoriously
> under-documented by MS, it is anybody's guess what such names can do
> in what APIs.

OK, thanks for explaining: I did not know about that syntax,
or about the behavior being undocumented and undefined.
Also, come to think of it, there will be problems with
drive prefixes.

Rather than try to fix these problems, which are on a platform
I'm not familiar with, I'll change the proposed code to
do the following.  This should be safe since it is what the
trunk currently does now (modulo some refactoring) when on
DOS or Windows platforms.  And it can be tuned for DOS and
Windows later, as needed.

/* If FILE is a searchable directory or a symlink to a
   searchable directory, return true.  Otherwise return
   false and set errno to an error number.  */
bool
file_accessible_directory_p (char const *file)
{
#ifdef DOS_NT
  /* File names may have drive prefixes and "/" is not the only
     separator, so the POSIXish approach doesn't work in general.
     Use a straightforward approach instead.  */
  return file_directory_p (file) && check_executable (file);
#else
  /* On POSIXish platforms, use just one system call; this avoids a
     race and is typically faster.  */
  ptrdiff_t len = strlen (file);
  char const *dir;
  bool ok;
  int saved_errno;
  USE_SAFE_ALLOCA;

  /* Normally a file "FOO" is an accessible directory if "FOO/." exists.
     There are three exceptions: "", "/", and "//".  Leave "" alone,
     as it's invalid.  Append only "." to the other two exceptions as
     "/" and "//" are distinct on some platforms, whereas "/", "///",
     "////", etc. are all equivalent.  */
  if (! len)
    dir = file;
  else
    {
      /* Just check for trailing '/' when deciding whether to append '/'.
         That's simpler than testing the two special cases "/" and "//",
         and it's a safe optimization here.  */
      char *buf = SAFE_ALLOCA (len + 3);
      memcpy (buf, file, len);
      strcpy (buf + len, "/." + (file[len - 1] == '/'));
      dir = buf;
    }

  ok = check_existing (dir);
  saved_errno = errno;
  SAFE_FREE ();
  errno = saved_errno;
  return ok;
#endif
}






reply via email to

[Prev in Thread] Current Thread [Next in Thread]