[Top][All Lists]

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

Broken 'test -x' behaviour for euid=0 on Solaris

From: Jonathan Perkin
Subject: Broken 'test -x' behaviour for euid=0 on Solaris
Date: Thu, 28 Feb 2013 14:24:41 +0000
User-agent: Mutt/1.5.21 (2010-09-15)

The implementation-defined behaviour of access() and faccessat() on Solaris is
as follows:

    If any access permissions are to be checked, each will be
    checked individually,  as  described  in  Intro(2).  If  the
    process has appropriate privileges, an implementation  may
    indicate  success for  X_OK  even  if  none of the execute file
    permission bits are set.

As such, 'test -x' performed as root will return true even for files
which are not executable:

  bash-4.2# uname -srvm
  SunOS 5.11 joyent_20120126T071347Z i86pc
  bash-4.2# echo $BASH_VERSION 
  bash-4.2# touch /var/tmp/foo
  bash-4.2# ls -l /var/tmp/foo
  -rw-r--r--   1 root     root           0 Feb 28 14:13 /var/tmp/foo
  bash-4.2# test -x /var/tmp/foo
  bash-4.2# echo $?
  bash-4.2# /bin/test -x /var/tmp/foo
  bash-4.2# echo $?

There is already handling for this chosen behaviour within sh_eaccess(), so it
is simply a matter of extending it for the faccessat() case, as implemented in
the patch below (against current git from git://git.sv.gnu.org/bash.git):

diff --git a/lib/sh/eaccess.c b/lib/sh/eaccess.c
index 534c526..453e328 100644
--- a/lib/sh/eaccess.c
+++ b/lib/sh/eaccess.c
@@ -206,7 +206,12 @@ sh_eaccess (path, mode)
     return (sh_stataccess (path, mode));
 #if defined (HAVE_FACCESSAT) && defined (AT_EACCESS)
-  return (faccessat (AT_FDCWD, path, mode, AT_EACCESS));
+  ret = faccessat (AT_FDCWD, path, mode, AT_EACCESS);
+#  if defined(SOLARIS)
+  if (ret == 0 && current_user.euid == 0 && mode == X_OK)
+    return (sh_stataccess (path, mode));
+#  endif
+  return ret;
 #elif defined (HAVE_EACCESS)           /* FreeBSD */
   ret = eaccess (path, mode);  /* XXX -- not always correct for X_OK */
 #  if defined (__FreeBSD__)

Chances are high that 'defined (__FreeBSD__)' should be added to this test too,
but I do not have any FreeBSD machines on which to verify this, so I have not
added it for now.

I have verified this fix on SmartOS, an illumos distribution.  As far as I am
aware, the faccessat() implementation has not diverged between illumos and
Solaris 11, but again I do not have access to a Solaris 11 system to verify
this for certain.


Jonathan Perkin  -  Joyent, Inc.  -  www.joyent.com

reply via email to

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