From 89e5b6ba033f08b6ea0d9756d523552b439c2d65 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sat, 6 Mar 2010 19:49:34 +0100
Subject: [PATCH] Clarify access, euidaccess, faccessat.

---
 ChangeLog                           | 11 +++++++++++
 doc/glibc-functions/euidaccess.texi | 12 ++++++++++++
 doc/posix-functions/access.texi     | 12 ++++++++++--
 doc/posix-functions/faccessat.texi  |  8 ++++++--
 lib/euidaccess.c                    | 10 +++++-----
 lib/unistd.in.h                     | 12 ++++++++++++
 6 files changed, 56 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e91b6cc3f6..89ab2e7018 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-03-06  Bruno Haible  <bruno@clisp.org>
+
+	Clarify access, euidaccess, faccessat.
+	* doc/posix-functions/faccessat.texi: Mention security problem under
+	"Other problems", not "Portability problems".
+	* doc/posix-functions/access.texi: Likewise. Mention a related security
+	problem.
+	* doc/glibc-functions/euidaccess.texi: Mention security problems.
+	* lib/euidaccess.c: Add comments about platforms.
+	* lib/unistd.in.h (access, euidaccess): Add warnings.
+
 2010-03-07  Bruno Haible  <bruno@clisp.org>
 
 	Ensure posix_spawnattr_{get,set}sched{policy,param} are defined.
diff --git a/doc/glibc-functions/euidaccess.texi b/doc/glibc-functions/euidaccess.texi
index 5e3939170f..bc43b40a00 100644
--- a/doc/glibc-functions/euidaccess.texi
+++ b/doc/glibc-functions/euidaccess.texi
@@ -15,3 +15,15 @@ IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x, mingw, Interix 3.5, BeOS.
 Portability problems not fixed by Gnulib:
 @itemize
 @end itemize
+
+Other problems of this function:
+@itemize
+@item
+There is an inherent race between calling this function and performing
+some action based on the results; you should think twice before trusting
+this function, especially in a set-uid or set-gid program.
+@item
+This function does not have an option for not following symbolic links
+(like @code{stat} versus @code{lstat}).  If you need this option, use
+the Gnulib module @code{faccessat} with the @code{AT_EACCESS} flag.
+@end itemize
diff --git a/doc/posix-functions/access.texi b/doc/posix-functions/access.texi
index 8da410d035..2609fa9368 100644
--- a/doc/posix-functions/access.texi
+++ b/doc/posix-functions/access.texi
@@ -16,8 +16,16 @@ Portability problems not fixed by Gnulib:
 This function uses the effective id instead of the real id on some
 platforms:
 Cygwin 1.5.x.
+@end itemize
+
+Other problems of this function:
+@itemize
 @item
 There is an inherent race between calling this function and performing
-some action based on the results; you should think twice before
-trusting this function in a set-uid or set-gid program.
+some action based on the results; you should think twice before trusting
+this function, especially in a set-uid or set-gid program.
+@item
+This function does not have an option for not following symbolic links
+(like @code{stat} versus @code{lstat}).  If you need this option, use
+the Gnulib module @code{faccessat} with the @code{AT_EACCESS} flag.
 @end itemize
diff --git a/doc/posix-functions/faccessat.texi b/doc/posix-functions/faccessat.texi
index f1d7be096e..b553beabaf 100644
--- a/doc/posix-functions/faccessat.texi
+++ b/doc/posix-functions/faccessat.texi
@@ -19,8 +19,12 @@ it is not safe to be used in libraries and is not multithread-safe.
 
 Portability problems not fixed by Gnulib:
 @itemize
+@end itemize
+
+Other problems of this function:
+@itemize
 @item
 There is an inherent race between calling this function and performing
-some action based on the results; you should think twice before
-trusting this function in a set-uid or set-gid program.
+some action based on the results; you should think twice before trusting
+this function, especially in a set-uid or set-gid program.
 @end itemize
diff --git a/lib/euidaccess.c b/lib/euidaccess.c
index ba744d5cf7..29efc2b64f 100644
--- a/lib/euidaccess.c
+++ b/lib/euidaccess.c
@@ -78,15 +78,15 @@
 int
 euidaccess (const char *file, int mode)
 {
-#if HAVE_FACCESSAT
+#if HAVE_FACCESSAT                      /* glibc */
   return faccessat (AT_FDCWD, file, mode, AT_EACCESS);
-#elif defined EFF_ONLY_OK
+#elif defined EFF_ONLY_OK               /* IRIX, OSF/1, Interix */
   return access (file, mode | EFF_ONLY_OK);
-#elif defined ACC_SELF
+#elif defined ACC_SELF                  /* AIX */
   return accessx (file, mode, ACC_SELF);
-#elif HAVE_EACCESS
+#elif HAVE_EACCESS                      /* FreeBSD */
   return eaccess (file, mode);
-#else
+#else       /* MacOS X, NetBSD, OpenBSD, HP-UX, Solaris, Cygwin, mingw, BeOS */
 
   uid_t uid = getuid ();
   gid_t gid = getgid ();
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index f9fef506ce..f3cf9ad246 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -146,6 +146,13 @@ extern "C" {
 #endif
 
 
+#if defined GNULIB_POSIXCHECK
+/* The access() function is a security risk.  */
+_GL_WARN_ON_USE (access, "the access function is a security risk - "
+                 "use the gnulib module faccessat instead");
+#endif
+
+
 #if @GNULIB_CHOWN@
 # if @REPLACE_CHOWN@
 #  undef chown
@@ -269,6 +276,11 @@ _GL_WARN_ON_USE (rpl_environ, "environ is unportable - "
    the current process.  */
 extern int euidaccess (const char *filename, int mode) _GL_ARG_NONNULL ((1));
 # endif
+# if defined GNULIB_POSIXCHECK
+/* Like access(), this function is a security risk.  */
+_GL_WARN_ON_USE (euidaccess, "the euidaccess function is a security risk - "
+                 "use the gnulib module faccessat instead");
+# endif
 #elif defined GNULIB_POSIXCHECK
 # undef euidaccess
 # if HAVE_RAW_DECL_EUIDACCESS
-- 
2.30.2