bug-bash
[Top][All Lists]
Advanced

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

Re: access(2) shouldn't be used with test(1)


From: Eric Blake
Subject: Re: access(2) shouldn't be used with test(1)
Date: Tue, 20 Jul 2010 12:28:38 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100621 Fedora/3.0.5-1.fc13 Lightning/1.0b2pre Mnenhy/0.8.3 Thunderbird/3.0.5

On 07/20/2010 12:00 PM, Garrett Cooper wrote:
>     According to the POSIX spec, using access(2) is implementation
> dependent when running as superuser [1].

But as long as the answer is correct, then the access(2) family of calls
is the right thing to use.

> FreeBSD intentionally returns
> true whenever euid/uid = 0 [2].

Remember, POSIX allows an OS where the superuser CAN read/write/execute
any file it wants, regardless of whether there are explicit permission
bits set in the stat() results.  If FreeBSD is one of the OS's where the
superuser can execute a file that doesn't have any x bits set in stat(),
then that's one of the privileges of being the superuser, and their
implementation of access(X_OK) always returning true is correct.  On the
other hand, POSIX suggests that a better implementation is that the
superuser should only be able to arbitrarily execute files if the stat()
and ACL bits allow execute permissions to at least one entity (whether
or not that entity is also the superuser), in which case, blindly
returning true for access(X_OK) for uid 0 on a file with no other
execute permissions would be a bug in access().

Also, remember that access(2) takes into account ACLs, but stat() does
not.  POSIX requires that 'test -x file' succeed for a non-superuser uid
that does not own a file with 700 stat() bits, but where the file also
has an ACL granting execute rights to that uid.

> FreeBSD's /bin/sh doesn't have this
> `issue' with test(1). Example:

I argue that either FreeBSD's /bin/sh or their access(2) is buggy; the
question now is which one.

> 
> $ ls -l typescript
> -rw-r--r--  1 gcooper  gcooper  37875 Jul 12 22:19 typescript
> $ sudo sh -c 'test -x typescript; echo $?'
> 1
> $ sudo bash -c 'test -x typescript; echo $?'
> 0

Try:

echo echo hi > foo
chmod 644 foo
sudo sh -c './foo'

If it prints hi, then bash is correct as-is, because FreeBSD falls into
the category of OSs that allow arbitrary superuser execution regardless
of whether any other entity has execute rights, which is allowed but not
recommended by POSIX.  On the other hand, if the superuser fails to
execute ./foo but access(2) says it can, then FreeBSD's access(2) is
broken, at which point bash should be working around the broken
access().  But I still argue that bash is correct for using the
access(2) family (actually, bash should be using faccessat(,AT_EACCESS)
[required by POSIX 2008] or the non-portable alternatives eaccess() or
euidaccess() in preference to access(2), because you want to know if the
file is executable for the effective id).

(I don't have root access to a FreeBSD machine at the moment, or I would
try this myself).

>     Code should be added to detect the mode via stat(2), instead of
> access(2) (the FreeBSD manpage also notes security issues with race
> conditions when using access(2), so access(2) use is discouraged).
>     If I can get the details for grabbing bash from cvs/svn/whatever,

Bash (unfortunately) is not available in a public repository.  Provide
any patch against the 4.1 sources instead; that's the latest publicly
available source.  But be aware that bash already has fallback code to
use stat() on systems with known-buggy access(2), and that your solution
must NOT interfere with correct test behavior on systems with ACLs (that
is, relying _solely_ on stat() is almost guaranteed to be wrong on any
platform with alternate access controls).

Meanwhile, if bash ever uses access() instead of faccessat(,AT_EACCESS)
on a POSIX 2008 platform, then that would be a bug worth fixing.

-- 
Eric Blake   eblake@redhat.com    +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]