9

If user works on an application that is dynamically linked, and system is being upgraded, is there any protection mechanism that prevents application corruption?

Or is it up to application?

  • Remember reading a Linux book about how you should use ln -sf when swapping over libraries, because the -f allowed you to "overwrite" the existing destination of the symbolic link with a new one, without it ever being "broken" (unlike if you did an rm followed by a ln -s). So before the command, library.so pointed to the old version, eg. library.so.4... after the command, it simply pointed to library.so.5 (or whatever) instead - without ever not pointing to a valid library. – Baard Kopperud Jul 23 '16 at 18:31
16

As mentioned by @Kusalananda, usually upgrades are done by removing the old file, and creating a new one with the same name. This will actually create a new file with a new inode, leaving the system free to use the old one as long as it is open.

As a simplified example, stuff like

rm /bin/cat
cp /new/version/of/cat /bin/cat

will create a logically new file, and works even though cat might be running. Same goes for libraries. (The above is an example, not a robust way of upgrading a file in the real world.)


Someone could try to change the binary in-place instead of creating a new one with the same name. In this case, at least Linux actually prevents making changes to an executable that is in use:

window 1 # ./cat
window 2 # echo foobar > cat
-bash: cat: Text file busy

However, this doesn't seem to work with dynamically loaded libraries...

I made a copy of libc.so.6 for testing, and filled it with zeroes while it was in use:

window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ldd ./cat
    linux-vdso.so.1 (0x00007ffcfaf30000)
    libc.so.6 => /tmp/lib/libc.so.6 (0x00007f1145e67000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f1146212000)

window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ./cat
foo
foo

Segmentation fault

(Meanwhile in another window, after the foo, before the segfault)

window 2 /tmp/lib# dd if=/dev/zero of=libc.so.6 bs=1024 count=2000

There's really nothing the program itself could do against this, since I effectively edited its code online.

(This would likely be system dependant, I tested on Debian Jessie 8.5, Linux 3.16.7-ckt25-2+deb8u3. IIRC Windows systems in particular are even more aggressive about preventing in-use files from being modified.)


So I guess the answer is that upgrades are usually done in an way that avoids any problems, and this is helped by the filesystem internals. But (on Linux) there don't seem to be any safeguards against actually corrupting dynamic libraries.

  • The install utility is commonly used for stuff like this. You don't need to explicitly rm the destination file. Plus it preserves the permissions of the existing file, can make a backup, set a new mode, etc. Example usage: install /new/version/of/cat /bin/cat – Patrick Jul 23 '16 at 13:21
  • Sure. The rm+cp was meant as an example. It might also be smart to put the new file in place atomically with a rename, the avoid a short window in which neither version is available. (Though GNU install doesn't even seem to do that, hmpf.) – ilkkachu Jul 23 '16 at 13:37
  • 2
    I would like to make clear something that is in this answer: In Unixes if a file is open, and removed (rm), then it is not yet deleted. It will exist on disk and can still be read by all processes that have it open. It will only be deleted when its hard-link count reaches zero AND the number of precesses with the file open reaches zero. – ctrl-alt-delor Jul 23 '16 at 17:41
  • @Patrick: The install utility is specifically unsafe! It overwrites the target file in place rather than atomically replacing it. mv (with source and dest in same directory, source usually a temp file) is the only safe way to install files. – R.. Jul 24 '16 at 2:27
  • 1
    @Patrick as far as my strace tells, install in GNU coreutils unlinks the target file and then copies a new one in its place. Which means that there is a short window during which the file is partial. It doesn't set the file atomically in place with a rename. – ilkkachu Jul 24 '16 at 18:02
3

Files won't be "properly deleted" if they are unlinked while they are still opened. When they are closed, the disk space that they used will be considered "free" again. This goes for currently running applications and their shared libraries as well.

The only thing that I could see failing would be if a program used dlopen() to load a shared library on demand, or if the program had to access other files on demand such as dictionaries, theme files, or other files that suddenly disappeared.

To illustrate: Running vim in one shell session while deleting the installation of vim in another shell session won't "corrupt" or terminate the currently running vim session. But some things will start to fail, like spell checking for example, which requires vim to open files in its installation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.