4 ms·
With TOCTOU, the solution is often just to try to use the resource and handle errors, not to assume that since you checked it, it's available.
by ijustlovemath 2y ago
With TOCTOU, the solution is often just to try to use the resource and handle errors, not to assume that since you checked it, it's available.
- loeg 2y agoPID reuse is the classic example here. There is no neat solution other than process handles, which Unix/Linux does not historically have.
- fc417fc802 2y agoAren't process handles still an integer under the hood in the end? The solution is presumably the same - use enough bits.
- int_19h 2y agoWhat makes process handles different is that they have a lifetime of their own that is distinct from the lifetime of the process - even if the process exits, the handle still refers to that now-dead process, not to some random new process, until you release the handle.
- fc417fc802 2y agoBut if it's still an integer (that you can't see) then it's still subject to reuse to the exact same extent that an integer is or isn't. It's entirely possible to wrap your internal integer at 16 bits and experience handle collisions. Alternatively you are free to use full 64 bit integers on Linux (at least IIUC). If you can architect a system that never experiences handle collision then quite trivially you can architect an equivalent system that never experiences PID reuse.
- int_19h 2y agoYou're missing the point. No, handles are not subject to such a problem because their lifetimes are explicit and distinct from the underlying resource. E.g. in Win32, if you have a process handle, it will not ever refer to a process different from the one that it was originally created for until you specifically call CloseHandle on it. The OS will retain that handle in its table and will not reuse it for any other process. And yes, of course it would be trivially easy to do the same in Linux. Except for that whole part where it would break all the existing code relying on POSIX semantics.
- fc417fc802 2y ago[dead]
- IshKebab 2y agoThat only works if you know the resource in advance. Doesn't work if for example you're trying to delete files matching a glob and you have to enumerate them by name and then delete them by name. The filesystem API offers a solution for that. The process API doesn't (maybe with procfd; I haven't tried that API yet since it's so new).
- ijustlovemath 2y agoI'm not sure that counts as TOCTOU? What I'm saying is that instead of writing code like: for fname in someglob: if os.path.exists(fname): os.unlink(fname) You should instead write for fname in someglob: os.unlink(fname) and handle the errors.
- kelnos 2y agoThis isn't a TOCTOU problem. This is a problem of using sentinel values to mean other things, when those sentinel values won't ever get returned by getpid(), but kill() will accept those values and do something you didn't intend. The fix was to check if the PID variable was set to one of the sentinel values, and not call kill() at all if that's what they are.