misleading error message for SELinux denials
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
mksh |
Fix Released
|
Wishlist
|
Unassigned |
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="/
here's what strace says happened:
newfstatat(
write(2, "/system/bin/sh: /system/
) = 44
versus the normal `chmod a-x` case where stat succeeds but access fails:
newfstatat(
faccessat(AT_FDCWD, "/data/
write(2, "sh: /data/local/
) = 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
or, if you're not into the whole SELinux thing, here's a repro case just using chmod on debian:
cd tmp
mkdir d
touch d/f
chmod 000 d
mksh -c /tmp/d/f
mksh: /tmp/d/f: not found
bash -c /tmp/d/f
bash: /tmp/d/f: Permission denied