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

2015-10-10 Thread Chet Ramey
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 

bad handling of error conditions in "type -P'

2015-10-09 Thread Linda Walsh

I've run across several problems with how type -P returns errors.

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

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

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

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.

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

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.

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

Proposals:
1) It seems the non-posix mode should parallel the posix mode in
this case.
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'.
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).

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?

Cheers,
L. Walsh





bad handling of error conditions in "type -P'

2015-10-09 Thread Linda Walsh



There are several problems with how type -P returns errors.

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

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

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

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.

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

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.

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

Proposals:
1) It seems the non-posix mode should parallel the posix mode in
this case.
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'.
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).

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?

Cheers,
L. Walsh