Suppose setuid
/setgid
bits are of no concern. Why is there a separate permission for execution?
Philosophically, it feels to me that the write permission subsumes the read permission, and that the read permission subsumes the execute permission. Of course, things aren't this way in Linux, and this can sometimes be useful, but I would reckon that it rarely is.
For instance, if a process can read a file that isn't executable, then as long as that process can write in some directory, it can simply copy the file there, set the execute bit, and then run that program. So truly, read subsumes execute in simple cases.
Obviously this isn't going to work properly if the source file has the setuid bit, or if the process can only write in noexec mount points.
The reason that I ask is that I'm implementing a Linux syscall that would allow a process to exec
an arbitrary chunk of its memory. (The specific use case is that I have a full program bundled within my main program, and I don't want to write it to disk in order to call execve
.) Are there any serious concerns with such a syscall that I should be aware of?
Best Answer
As you surmise, the execute permission is rarely useful as a permission. Having it as a permission rather than an attribute of the file is a bit of a historical accident. However, since it exists, it isn't going to go away. Having an execute permission that's distinct from the read permission matters in two cases.
chmod
, or may only be allowed to write to directories on a filesystem that's mounted withnoexec
. Such a user is restricted to the executable files that already exist.Adding a system call to exec from memory allows restricted accounts to execute arbitrary code. It's equivalent to having a native code interpreter that's accessible from everywhere, even restricted accounts. This wouldn't be accepted in the mainstream kernel since it would break security restrictions. You can deploy it on your own machines but you should keep the implications in mind.
However, it's a lot of work and a lot of security baggage to carry for a feature that already exists. It is possible to execute code without writing to disk. You just have to write the code to a file on a non-disk filesystem such as tmpfs.