4 ms·
I read once that all OS code callable from a process begins with a NOP instruction, allowing an update to drop in a jump to the new version of that function by
by billpg 8y ago
I read once that all OS code callable from a process begins with a NOP instruction, allowing an update to drop in a jump to the new version of that function by replacing the NOP.
I had to wonder why given that is available, why reboots on updates are required at all.
- barrkel 8y agoShared libraries - dlls - are not reloadable like this. In fact they usually can't be deleted at all if they're in use, renamed at best, and that is risky if it's something that is dynamically loaded and is part of a dependency graph. I'd expect the majority code covered by an update to be in shared libraries.
- majewsky 8y agoIsn't that just a deficiency of Windows' filesystem implementation, though? On Linux, you can absolutely overwrite libraries that are still used by running applications. The OS will just not reclaim the disk space until all those processes end (e.g. by means of reboot), but new processes will start using the new libs immediately.
- invokestatic 8y agoWindows memory-maps the DLL file from disk into virtual memory (a la MapViewOfFile), causing the filesystem lock. While I’m not sure why this was done, I speculate it has something to do with saving memory back in the 9x days or even earlier. It’s possible to write a DLL loader that reads from the file once and copies the bytes to memory, leaving no lock unlike memory mapping the file. But even so, there’d be no way to reliably reload DLLs running in a process, not to mention that there are usually hundreds of them running in any particular process. I can also imagine issues arising if existing processes continue to run an old DLL where a new process has a newer, updated DLL such as with IPC, or if there is a zero-day in a DLL used by a long-running daemon. All around, restarting is the safest bet.
- fencepost 8y agoOn Linux, you can absolutely overwrite libraries that are still used by running applications. The OS will just not reclaim the disk space until all those processes end (e.g. by means of reboot), but new processes will start using the new libs immediately. Which if you're not careful could lead to undetectably unpatched systems - installed version is up to date, files on disk match if you check to verify, but some process that didn't get properly restarted is still using the (effectively) undetectable old version. Combine that with taking pride in triple digit uptime days and you could have something sticking around for a long time.
- icebraining 8y agoIt's not undetectable; just run "pmap [pid]" and it will show the loaded libraries with "(deleted)" at the front if the original file no longer exists: https://stackoverflow.com/questions/4786975/what-is-a-deleted-segment-in-linux-pmap-output https://stackoverflow.com/questions/4786975/what-is-a-delete...
- fencepost 8y agoThat's both a correct and useful answer and one that proves my point in practical terms. If you know enough to run pmap over the process space of the server to look for issues like this, you also know enough to force restarts of the affected services post-update. I could see this being something to add to automated monitoring tools run on a schedule, but I don't know enough to estimate the viability or usefulness of actually doing so - would it end up being a rule that in 99.999% of cases would only actually match if it happened to fire as the server was in the process of shutting down?
- icebraining 8y agoTooling around that already exists: if you install the needrestart package on Debian, it will check every time apt upgrades something, so that you can restart daemons and such.
- userbinator 8y agoYou miss the whole point of the parent comment --- it's referring to the fact that the binaries can be patched in memory as well as on disk. Renaming and deleting upon the next reboot is perfectly reasonable and gets you something similar to the POSIX behaviour (existing processes continue to hold the old version open, new processes will use the new version.)
- userbinator 8y agoYou can do that even without the NOPs or any other special preparation beforehand --- API hooking is one example that's used all the time, and there's no shortage of code samples out there to do it.
- gruez 8y agothe point of using a nop is that the patch can be done atomically. otherwise you run into race conditions if a thread's currently executing the instruction(s) you're patching.
- userbinator 8y agoGiven that the patching mechanism can (must --- due to what gets updated sometimes) be implemented in kernel mode, it's not hard to ensure that all threads are away from the "construction zones", even a "stop the world" type scan if necessary, which is still going to be far less disruptive than rebooting. The point is that this is not an open problem, and has been solved before multiple times.
- wmf 8y agoLive updates are cool but they're also risky; if you haven't booted the current configuration you don't know if it will boot when you need it to.