On 12/14/2010 07:28 PM, Lennart Poettering wrote:
In order to make things secure we minimize what is allowd on the various API file systems we mount. That includes that we set noexec and similar options for the file systems involved. The interface how to access /dev/shm is called shm_open(), and given that this is how it is there is very little reason to allow people to execute binaries from them. Of course, this is a very recent change, and at this point while we assume that this will not break any valid use of this directory, we cannot be sure about this, so we'd be very interested to learn why exactly you want the noexec to be dropped. What is your application that needs that? If there is a point in dropping the noexec, we'll definitely be willing to do so, but if the only reason would be "I always misused /dev/shm as a scratch space", then we won't be very convinced. The API fom /dev/shm is shm_open(), and if you place other stuff in there, then you are misusing it and actually creating all kinds of namespacing problems (since /dev/shm is actually an all-user shared namespace), and we aren't particularly keen to support such misuses by default.
The claim "The API for /dev/shm is shm_open()" is incorrect. Very early in the history of shm [late 1970's at the Columbus, Ohio, USA branch of Bell Telephone Laboratories], then shm_open, shmget, etc., were the only means of access; the objects had names that were 32-bit binary integers. In fact, when shm became more widely used then there were denial-of-service attacks based on the premise that enumerating objects in shm required 2**32 exhaustive search via shmget. As soon as /dev/shm was integrated into the filesystem, then creat, open, read, write, close, lseek, execve, etc. (any filesystem API) became additional access paths. This integration began appearing by about the mid 1980's, around 25 years ago, and since then applications have been using /dev/shm via ordinary files system APIs in addition to shmget etc.
Why? Because *fast* operations on small numbers of small-to-medium-sized files can be a big advantage for performance. /tmp often is much slower because /tmp often is a harddrive: the need for space in /tmp often exceeds the size of physical RAM. Also, mounting /tmp as tmpfs can meet resistance because tmpfs does not support all features that applications expect. A ramdisk might be used, except that early ramdisks allowed at most a few megabytes (comparable to the capacity of a floppy disk), which is not large enough to support typical simultaneous usage. Applications also cannot rely on ramdisks because superuser privileges usually are required to access a ramdisk. In many cases ramdisks have been replaced by: /dev/shm !!
I have applications which use /dev/shm via file system APIs, including execve() and dlopen(). Both of those fail when /dev/shm has MS_NOEXEC. One group of applications generates database plugins on-the-fly in a just-in-time fashion. Of course non-interactive performance increases in the usual way that substituting compiled code for interpreted often gives a speedup of 8X or more. Interactive response also improves, because small files in /dev/shm do not contend with operations in /tmp which can require slow sync() or large transfers. In some cases even /dev/shm is slower than desirable. I have requested dlopen() from memory: http://sourceware.org/bugzilla/show_bug.cgi?id=11767 . Meanwhile, /dev/shm is the only choice which is present always and sufficiently fast.
It is just not true that file system APIs are a misuse of /dev/shm.
--