[Top][All Lists]

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

Re: Built-in "test -x" fails for root on FreeBSD

From: Eric Blake
Subject: Re: Built-in "test -x" fails for root on FreeBSD
Date: Mon, 29 Mar 2010 08:01:46 -0600
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv: Gecko/20100301 Fedora/3.0.3-1.fc12 Lightning/1.0b1 Thunderbird/3.0.3

On 03/26/2010 11:47 PM, Johan Hattne wrote:
> Description:
>   The bash built-in test command fails to correctly report executable
>   status for non-executable files when run by root on FreeBSD.

Not a bug.  POSIX states for test -x:

True if pathname resolves to an existing directory entry for a file for
which permission to execute the file (or search it, if it is a
directory) will be granted, as defined in File Read, Write, and Creation.

It further states:

If a process has appropriate privileges:
    * If read, write, or directory search permission is requested,
access shall be granted.
    * If execute permission is requested, access shall be granted if
execute permission is granted to at least one user by the file
permission bits or by an alternate access control mechanism; otherwise,
access shall be denied.


It also states for faccessat (eaccess is a non-portable interface
comparable to the standardized faccessat):

If any access permissions are checked, each shall be checked
individually, as described in XBD File Access Permissions , except that
where that description refers to execute permission for a process with
appropriate privileges, an implementation may indicate success for X_OK
even if execute permission is not granted to any user.

Therefore, it is perfectly acceptable for the root user to claim that a
file is executable, as reported by eaccess, even if none of the file
permission bits grant such permission.

>  #if defined (HAVE_EACCESS)        /* FreeBSD */
> -  return (eaccess (path, mode));
> +  if (stat (path, &s) != 0)
> +    return (-1);
> +  ret = eaccess (path, mode);
> +  if (mode == X_OK && ret == 0 && !S_ISDIR(s.st_mode) && geteuid() == 0)
> +    return ((s.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0 ? -1 : 0);
> +  return (ret);

This patch fails to take into account ACLs, which is one of the reasons
that faccessat was standardized.

Eric Blake   address@hidden    +1-801-349-2682
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature

reply via email to

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