3 ms·
Stat then dlopen is a toctou (time of check/time of use) bug. There's a race condition between the check succeeding and the dlopen being called in which that li
by zahllos 6y ago
Stat then dlopen is a toctou (time of check/time of use) bug. There's a race condition between the check succeeding and the dlopen being called in which that library might be replaced by a malicious one.
Like all race condition bugs it is probabilistic, but it can be won. By contrast dlopen either succeeds or does not, and once you have the handle to the library you are good.
Actually windows also works this way, and has done since wow I think vista if not XP? There's a knowndlls registry key. Large parts of the windows api are contained in a few DLLs; these are loaded on system startup. When resolving shared libraries if one of these names is requested the normal DLL loading procedure of checking paths isn't even followed - it just links in the already loaded DLL from the cache.
It actually wasn't designed as a security feature, but for speed. No matter what the OS does there's little need to continually load these DLLs from disk when we know they are already loaded to even display the desktop.
Of course on windows you can still do the windows equivalent of stat'ing these DLLs but nobody ever does.
- wahern 6y ago> It actually wasn't designed as a security feature, but for speed. No matter what the OS does there's little need to continually load these DLLs from disk when we know they are already loaded to even display the desktop. FWIW, this optimization is unnecessary on modern Unix systems with a unified buffer cache because libraries loaded from disk are already CoW'd into the user process, without the need for special semantics. It's a pertinent point, nonetheless, but I'm guessing Apple made the switch in macOS for other reasons, perhaps related to disk space, its less than ideal ASLR scheme for Mach-O, or something related to code signing and sandboxing. I second the TOCTOU concern. It's a bad code smell and a poor habit to stat and then open a file, period. (Likewise for the more general pattern.) There are reasons to do it (some better than others), but they're exceptional. You should never be eager to do it, and when you do you should rule out all possible security exploits or bugs, which is usually more work than abstaining from the superfluous hack. Breaking such code patterns is worth the cost in backward compatibility, IMO, for all the exploits and usability headaches this coding pattern leads to.