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: Garrett Cooper
Subject: Re: access(2) shouldn't be used with test(1)
Date: Tue, 20 Jul 2010 11:52:25 -0700

On Tue, Jul 20, 2010 at 11:28 AM, Eric Blake <eblake@redhat.com> wrote:
> 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().

Yeah, the manpage gives access(2) the `license to lie':

     Even if a process's real or effective user has appropriate privileges and
     indicates success for X_OK, the file may not actually have execute per-
     mission bits set.  Likewise for R_OK and W_OK.

> 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.

Hmmm...

>> 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.

Technically it's test(1) that's reporting the mode info, and what they
do is use eaccess(2) instead of access(2).

>> $ 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).

Yeah, it fails:

$ echo echo hi > foo
$ chmod 644 foo
$ sudo sh -c './foo'
./foo: Permission denied

>>     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.

    I see the quandary now (thanks for the clarification). FreeBSD
supports POSIX ACLs and MAC, so yes, it does appear that access(2) (or
rather the underlying callers for it) should be fixed. I'll have to
check faccessat(2) to see whether or not it's buggy by writing
unittests for it (*sigh*). At least I'll integrate them into the
open_posix_testsuite in ltp, which means they'll be available for
Linux as well...

Thanks,
-Garrett



reply via email to

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