noexec on /dev/shm

John Reiser jreiser at bitwagon.com
Wed Dec 15 05:55:07 UTC 2010


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.

-- 


More information about the devel mailing list