Are you referring to Posix 1003.1 section "C.2.8.2 Exit Status for
Commands"?

  Historical shells make the distinction between ‘‘utility not found’’ and
  ‘‘utility found but cannot execute’’ in their error messages. By specifying
  two seldomly used exit status values for these cases, 127 and 126 
respectively,
  this gives an application the opportunity to make use of this distinction
  without having to parse an error message that would probably change from
  locale to locale. The command, env, nohup, and xargs utilities in the
  Shell and Utilities volume of IEEE Std 1003.1-2001 have also been specified to
  use this convention.

(I may be viewing an out of date version... my apologies if so)

A few comments:

1) Based on the above, POSIX also seems to require different error
messages for "not found" and "found but cannot execute". The entire
reason this bug exists is because mksh is failing to return different
error messages when the executable exists but the stat() fails. The
proposal from comment #8 seems to acknowledge this non-compliance, yet
not address it.

2) The stat() is unnecessary for distinguishing between a 126 and 127
error status. Instead, a much simpler way is to just execve() the file,
return 127 iff errno==ENOENT. I believe this is all Posix requires.

3) Manually checking permission bits is not an accurate indicator of
whether the file can be executed or not, primarily due to LSMs.

4) Calling stat() unnecessarily inhibits certain use cases, specifically
comment #7.

5) A failure of the stat() system call is not an accurate indicator of
the exec()-ability of the file. The only way to determine if a file is
executable is to execute it.

-- 
You received this bug notification because you are a member of mksh
Mailing List, which is subscribed to mksh.
Matching subscriptions: mkshlist-to-mksh-bugmail
https://bugs.launchpad.net/bugs/1817789

Title:
  misleading error message for SELinux denials

Status in mksh:
  Opinion

Bug description:
  Given a stat(2) failure caused by an SELinux denial (rather than a
  stat(2) success and an access(2) failure, as with a regular `chmod
  a-x` failure), mksh reports "not found" rather than the more correct
  "Permission denied".

  Expected:
  * Permission Denied error message

  Actual:

    $ sh -c /system/bin/vold
    sh: /system/bin/vold: not found

    "not found" error message.

  
  here's the behind-the-scenes SELinux denial:

  02-25 22:37:11.023  4571  4571 W sh      : type=1400 audit(0.0:347):
  avc: denied { getattr } for path="/system/bin/vold" dev="dm-0" ino=717
  scontext=u:r:shell:s0 tcontext=u:object_r:vold_exec:s0 tclass=file
  permissive=0

  
  here's what strace says happened:

  newfstatat(AT_FDCWD, "/system/bin/vold", 0x7ffcc3ef20, 0) = -1 EACCES 
(Permission denied)
  write(2, "/system/bin/sh: /system/bin/vold"..., 44/system/bin/sh: 
/system/bin/vold: not found
  ) = 44

  versus the normal `chmod a-x` case where stat succeeds but access
  fails:

  newfstatat(AT_FDCWD, "/data/local/tmp/date2", {st_mode=S_IFREG|0644, 
st_size=482560, ...}, 0) = 0
  faccessat(AT_FDCWD, "/data/local/tmp/date2", X_OK) = -1 EACCES (Permission 
denied)
  write(2, "sh: /data/local/tmp/date2: can't"..., 60sh: /data/local/tmp/date2: 
can't execute: Permission denied
  ) = 60

  
  this patch fixes the issue:

  ```
  diff --git a/src/exec.c b/src/exec.c
  index 8330174..3f6d876 100644
  --- a/src/exec.c
  +++ b/src/exec.c
  @@ -1279,8 +1279,8 @@ search_access(const char *fn, int mode)
          struct stat sb;
   
          if (stat(fn, &sb) < 0)
  -               /* file does not exist */
  -               return (ENOENT);
  +               /* file may or may not exist: check errno */
  +               return errno;
          /* LINTED use of access */
          if (access(fn, mode) < 0) {
                  /* file exists, but we can't access it */
  ```

  i don't know if you want to elaborate further in the comment along the
  lines of "...for example, an SELinux denial may mean that we get
  EACCES here, or if the file doesn't exist and we're allowed to know
  that, we'll get ENOENT".

  
  result with patch:

  $ sh -c /system/bin/vold
  sh: /system/bin/vold: can't execute: Permission denied

To manage notifications about this bug go to:
https://bugs.launchpad.net/mksh/+bug/1817789/+subscriptions

Reply via email to