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 c...@case.edu http://cnswww.cns.cwru.edu/~chet/