On Fri, Jun 07, 2013 at 09:09:53PM +0800, jida...@jidanni.org wrote: > Well OK but sometimes a script could be running for years, during which > any change to a file will result in bash executing random bytes...
This is why you don't edit an installed script in-place. Instead, you move it aside, or remove it, or hardlink it, or do some other fancy thing. # This is the naive way. It is bad because an already-running shell reading # the script as input may get garbled text. Also, there is a period of # vulnerability where the new script is only partially written to disk; # anyone running the script at that time may just get part of it. Finally, # the old script is not preserved, so if the OS crashes during the copy, # you have neither the old one nor the new one. cp myscript /usr/local/bin # This looks better at first glance, and it dodges the problems of mixing # old and new text in an already-running shell, but it leaves a period of # vulnerability where there's no installed script, or where there's a # partially installed script, and it doesn't prevent loss of the old script # if the OS crashes during the copy. So, this is still bad. rm /usr/local/bin/myscript && cp myscript /usr/local/bin # This one is only slightly better. It preserves the old script in case # the OS crashes during the copy, which allows for manual rollback, but # it still leaves that vulnerable period where someone could invoke the # script while it's only partially copied. mv /usr/local/bin/myscript /usr/local/bin/myscript.bak && cp myscript /usr/local/bin # This is better. The mv is atomic, so there is no period of vulnerability # during which the script is either missing or partially installed. cp myscript /usr/local/bin/myscript.tmp && mv /usr/local/bin/myscript.tmp /usr/local/bin/myscript # Alternative, maintaining several installed versions on disk simultaneously. # The installed "script" is really a symlink. The ln is atomic, so this # also avoids all the issues, as long as you never use the same version # number more than once. cp myscript /usr/local/bin/myscript-some.version.number && ln -sf myscript-some.version.number /usr/local/bin/myscript