On Wed, 16 Jun 2010, Richard Matthew McCutchen wrote:

I noticed the following funny behavior on Linux:

$ cp /bin/bash /lib64/libc.so.6 .
$ LD_LIBRARY_PATH=. ./bash
   # In the subshell...
$ >bash
bash: bash: Text file busy
$ >libc.so.6
Bus error (core dumped)

So evidently the kernel prevents executables from being overwritten
while in use, but there is no analogous feature for shared libraries.
It seems to me that there should be.

I notice that glibc passes MAP_DENYWRITE when mapping the shared
portions of shared libraries.  The mmap(2) man page says:

      MAP_DENYWRITE
                       This flag is ignored.  (Long ago, it signaled
                       that attempts to write to the underlying file
                       should fail with ETXTBUSY.  But this was a
                       source of denial-of-service attacks.)

Hmm... so executing a file is also a denial-of-service attack.  Maybe a
reasonable compromise would be to honor MAP_DENYWRITE for files on which
the process has execute permission.  Alternatively, the kernel could be
enhanced so that writes to a file never affect pre-existing private
mappings (the behavior is currently undefined), but I imagine that would
be a lot more work.

Thoughts?  What would be the right place to raise this issue: LKML?

--
Matt



POSIX might have something to say about this. FWIW, using dlopen to access the shared library instead of linking at compile time doesn't make a difference. I assume you are already familiar that deleting an open file is allowed and the file sticks around on disk until all processes have closed it. I saw an interesting article (somewhere) about the fact that Windows won't do this and how it is related to needing to reboot so often after updates.

Maybe there are some legitimate reasons for writing to an open shared library, such as strip --strip-debug on the C library as a contrived example?

As a related issue, read() is not allowed on directories on Linux. On a lot of historical Unix systems it is allowed and allows access to the on-disk structure of the directory. write() on a directory has *never* been allowed. More details in "The Unix Programming Environment."

Reply via email to