bug-bash
[Top][All Lists]
Advanced

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

Re: bad handling of error conditions in "type -P'


From: Chet Ramey
Subject: Re: bad handling of error conditions in "type -P'
Date: Sat, 10 Oct 2015 15:25:31 -0400
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0

On 10/9/15 8:17 AM, Linda Walsh wrote:
> 
> 
> There are several problems with how type -P returns errors.

`type -P', and `type' in general, reflects what would happen when a name is
used as a command.

> 1) if a file isn't executable, type returns it anyway in
>>  ls -l /sbin/scat
> -r--r--r-- 1 root root 245663 Nov 19  2013 /sbin/scat
>>  type -P scat            
> /sbin/scat

Because, in the absence of any other executable with that name, bash
will attempt to execute the first file it finds with that name in any
directory in $PATH, even if it doesn't have execute permission.  Bash
has always done this, from the earliest pre-1.0 days.

> 
> 2) if a file is inaccessible, type still returns it an answer for
>   the path of an executable named 'scat1':
>>  ls -l /sbin/scat1
> ---------- 1 root root 245663 Nov 19  2013 /sbin/scat1
>>  type -P scat1
> /sbin/scat1

For the same reason.

> 
> 3) bash "knows better" because it doesn't do this in "posix mode"

Yeah.  When in Posix mode, the behavior of returning a file that doesn't
have execute permission is inhibited.  I changed this in bash-3.1 for
compatibility with other shells claiming Posix conformance.  Posix doesn't
exactly address this, but other Posix shells behaved differently.  It
doesn't change the historical bash default behavior.

> 
> 4) if it doesn't find the file it returns a status
>   code meaning 'EPERM' rather than 'ENOENT'.
>   (ENOENT          No such file or directory (POSIX.1))
>   This is true in normal  mode or posix mode.

This doesn't make any sense.  If the file isn't present, type returns
1 (failure).  If it's found, but doesn't have the right permissions to
execute -- and no other file with that name with appropriate permissions
is found -- bash will try and execute it, so `type -P' returns a status
that indicates that it will attempt execution.

> 
> 5) if the file is executable for root, it is still return as
>   an answer for 'type -P':
>>  ls -l /sbin/scat2
> ---x------ 1 root root 245663 Nov 19  2013 /sbin/scat2
>>  type -P scat2
> /sbin/scat2

For the same reason as above.

> 6) if bash is in posix mode it will find '/sbin/scat2'
>   only if the owner is root (good), BUT for a non-root
>   user, a return code of '1' is return whether it the
>   file exists or not. NOTE: by 'coincidence' on linux,
>   1=EPERM, which would be correct for /sbin/scat2, but
>   it also returns '1' for the "ENOENT" case.

`1' has no relationship to EPERM.  And I don't think you meant
to say `owner'.

As I said above, Posix mode essentially adds a permissions check
(using eaccess) to the last-ditch file found by the path search.
If the file is found, but eaccess says you can't execute it, `type'
returns 1.

The exit status has no relationship to the particular errno value.


> 7) if the file is NOT owned by root, type -P returns
>   the alien-owned file (this seems like it would be a security
>   risk -- but it is also in the kernel, so bash behaving
>   differently, though correct, would be inconsistent with
>   the insecure behavior of the kernel:
>>  ls -l /sbin/ucat2
> ---x--x--- 1 nobody nogroup 245663 Nov 19  2013 /sbin/ucat2
>>  type -P ucat2     #(normal user)
> # type -P ucat2     #(root user is unprotected)
> /sbin/ucat2

Because root can execute any file on which any execute permission
bit is set.  This is how Unix works.  (For simplicity, let's ignore
mount options or ACLs.)

> 
> Proposals:
> 1) It seems the non-posix mode should parallel the posix mode in
> this case.

I disagree.  The historical bash behavior will not change.

> 2) type should return 'EPERM' if it finds an executable owned
>   by someone else that isn't allowed execution by the caller.

> 3) if no file with any executable bits is set it should return
>   status 'ENOENT'.

This is not the historical bash behavior, and I don't think this is
sufficient to change it.

> 4) Ideally root would not behave differently from the normal
>   user case, since ownership by a non-priviledged user might
>   indicate a security problem, HOWEVER, this should be brought
>   to the attention of the kernel folks for an explanation why
>   root can execute files owned by suspect users.  Perhaps
>   Bash being different in this case would be a best course,
>   as it is doing a path seach, while in the kernel case,
>   it should only be allowed if an absolute path was given
>   (with no PATH search).

What's a `suspect user'?  Root can execute any file for which any
execute bit is set.  If the kernel says a file is executable when
using eaccess(2), why does bash need to second-guess that?

> I regard this as rather broken, as it gives useless, wrong
> and insecure answers depending on the case. I also think
> bash, having had it's behavior changed due to posix rules should
> be using posix standard errno names, doesn't that make sense?

What does errno have to do with it?  What does `posix standard errno
names' mean?  You want an extra permissions check added to the
last-ditch return from the path search, or for that last-ditch return
to go away.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU    chet@case.edu    http://cnswww.cns.cwru.edu/~chet/



reply via email to

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