views:

51

answers:

3

If while an application is running one of the shared libraries it uses is written to or truncated, then the application will crash. Moving the file or removing it wholesale with 'rm' will not cause a crash, because the OS (Solaris in this case but I assume this is true on Linux and other *nix as well) is smart enough to not delete the inode associated with the file while any process has it open.

I have a shell script that performs installation of shared libraries. Sometimes, it may be used to reinstall versions of shared libraries that were already installed, without an uninstall first. Because applications may be using the already installed shared libraries, it's important the the script is smart enough to rm the files or move them out of the way (e.g. to a 'deleted' folder that cron could empty at a time when we know no applications will be running) before installing the new ones so that they're not overwritten or truncated.

Unfortunately, recently an application crashed just after an install. Coincidence? It's difficult to tell. The real solution here is to switch over to a more robust installation method than an old gigantic shell script, but it'd be nice to have some extra protection until the switch is made. Is there any way to wrap a shell script to protect it from overwriting or truncating files (and ideally failing loudly), but still allowing them to be moved or rm'd?

Standard UNIX file permissions won't do the trick because you can't distinguish moving/removing from overwriting/truncating. Aliases could work but I'm not sure what entirety of commands need to be aliased. I imagine something like truss/strace except before each action it checks against a filter whether to actually do it. I don't need a perfect solution that would work even against an intentionally malicious script.

A: 

Bash script I presume? Is the script very long? If not, you can do this manually:

if [ ! -f /tmp/foo.txt ] #If file does not exist
then
    ...code
fi

But I think you're asking for a way to wrap this around the script. You can certainly monitor the file writes with strace but AFAIK it doesn't have the functionality to interrupt them, unless you set up some sort of Intrusion Detection System with rules etc.

But to be honest, unless it's a huge script, that's probably more trouble than it's worth

waitinforatrain
+2  A: 

You can prevent a script from overwriting through I/O redirection by

set noclobber

Preventing overwriting by cp and the like is harder. My inclination would be to reset the PATH for the script to run with PATH containing just a single entry, a "blessed" directory where you place commands that you know are safe. This might mean, for example, that your version of cp is arranged always to use the --remove-destination option (probably a GNU-ism). In any case, you arrange for the script to execute only commands from the blessed directory. You can then vet each such command individually.

It would be good if you could prevent a script from executing a command by absolute pathname, but I don't know how to do that. If you are doing installations in your regular directories, a chroot jail probably does not help unless you do a lot of loopback mounting to make those directories visible. And if the directories into which you're installing contain dangerous commands, I don't see how you can protect yourself against them completely.

Incidentally, I tried and failed to learn if install(1) removes the desitination before installing. It would be interseting to learn.

Norman Ramsey
Those are both great suggestions. I'm curious for install as well because it's one of the utilities the script uses.
Joseph Garvin
For anyone coming across this later: It turns out the GNU version of install has a --backup option for it to "make a backup" of the file about to be overwritten. It's possible that it's savvy enough to mv the existing file to the backup named file rather than making a copy, but I haven't examined the source to be sure.
Joseph Garvin
A: 

Write your own safe_install() functions and make sure they're the only methods used. If you really need to be sure, run two processes. One would have permissions to make changes and the other would drop all privileges early and tell the other script to do the actual disk work.

Harvey