Re: [patch] remove MNT_NOEXEC check for PROT_EXEC mmaps

From: Stas Sergeev
Date: Wed Oct 04 2006 - 15:05:37 EST


Hi.

Jakub Jelinek wrote:
Even assuming ld.so would be hacked up so that it parses /proc/mounts
to see if you are trying to run an executable via ld.so from
noexec mount (which isn't going to happen),
No, the solution I wanted to evaluate, is "chmod 'go-x' ld.so".
For that to work, something like this is needed:
http://uwsg.ucs.indiana.edu/hypermail/linux/kernel/0609.3/2322.html
Then you can't invoke ld.so directly and if you happen to
have "noexec" on all the writeable mounts, then you can't
also use your own ld.so.

if mmap with PROT_EXEC
is allowed on noexec mounts, you can always put there a shared
library instead of a binary and put some interesting stuff in its
constructors and then just LD_PRELOAD=/dev/shm/libmyhack.so /bin/true
Of course if ld.so would check /proc/mounts, then it will
do so also for the shared libs, so LD_PRELOAD won't trick it.
I understand that parsing /proc/mounts is silly (I have
admitted that earlier in that thread already), but why not to
at least check the access(X_OK)? ld.so _must_ check access(X_OK)
before executing - why not yet?
Oh wait, access(X_OK) doesn't seem to work...
The attached patch is needed to get it working.
Does the patch look good? I think it was just a bug.

Really, if noexec is supposed to make any sense at all, it needs
to prevent PROT_EXEC mapping/mprotect, otherwise it is completely
useless.
Why not having an exec perm on a file doesn't prevent PROT_EXEC then?

In any case, guys, can the attached patch be applied?
Arjan, it enforces "noexec", just as you wanted to see. :)
Please say "no" now, not when I mail it to Andrew, if possible.

--- a/fs/namei.c 2006-08-29 14:15:47.000000000 +0400
+++ b/fs/namei.c 2006-10-04 11:28:52.000000000 +0400
@@ -249,9 +249,11 @@

/*
* MAY_EXEC on regular files requires special handling: We override
- * filesystem execute permissions if the mode bits aren't set.
+ * filesystem execute permissions if the mode bits aren't set or
+ * the fs is mounted with the "noexec" flag.
*/
- if ((mask & MAY_EXEC) && S_ISREG(mode) && !(mode & S_IXUGO))
+ if ((mask & MAY_EXEC) && S_ISREG(mode) && (!(mode & S_IXUGO) ||
+ (nd && nd->mnt && (nd->mnt->mnt_flags & MNT_NOEXEC))))
return -EACCES;

/* Ordinary permission routines do not understand MAY_APPEND. */