zlacker

[return to "Transcending Posix: The End of an Era?"]
1. sylwar+Zk[view] [source] 2022-09-10 13:33:57
>>jsnell+(OP)
Richard Stallman POSIX now will have to do one of the hardest stuff in the software realm: resist planned obsolescence while replacing some interfaces with "in-the-end better" interfaces, that on the long run. This is extremely though: often, replacing "in-the-end better" interfaces is actually planned obsolescence.

For instance event based programming, "epoll" should replace "select". Synchronous programming, signalfd, timerfd, etc... but then "signals" should be more accurately classified, for instance in monothreaded applications segfault won't be delivered from a "signalfd" in a "epoll" syscall... and why not keep only the "realtime signal" behavior?

If POSIX only "add" new "options", in the end, you'll get gigantic spec just being the mirror image of the very few implementations since its size will make it unreasonable for a new implementation from scratch.

The "leaner POSIX" route seems the right way here, but it is really easier to say than to do.

◧◩
2. bitwiz+2F[view] [source] 2022-09-10 15:51:42
>>sylwar+Zk
No, I/O completion ports (which Linux only recently got a form of) should replace epoll and select.

fork() should be ditched.

◧◩◪
3. thetea+Kg1[view] [source] 2022-09-10 19:49:07
>>bitwiz+2F
> fork() should be ditched.

Why? In favor of what?

◧◩◪◨
4. 10000t+fk1[view] [source] 2022-09-10 20:18:25
>>thetea+Kg1
Embryonic processes. Basically:

1. Call a function that creates an empty child process in a suspended state.

2. Call functions that: map/write memory into the child process’s address space; add file descriptors to the child process; set the child process’s initial register values; and so on.

3. Call a function to unsuspend and run the child process.

◧◩◪◨⬒
5. lgg+tq1[view] [source] 2022-09-10 21:19:35
>>10000t+fk1
fork() is terrible, but embryonic processes also have a lot of performance issues and prevent a number of valuable security mitigations. In general a spawn() style mechanism seems like a better approach (despite the deficiencies of specific examples like posix_spawn()).
◧◩◪◨⬒⬓
6. matu3b+0F1[view] [source] 2022-09-10 23:55:47
>>lgg+tq1
What is better in an unfixable race condition (the time before the execve where stuff leaks)?
◧◩◪◨⬒⬓⬔
7. lgg+yN1[view] [source] 2022-09-11 01:34:41
>>matu3b+0F1
I think it goes without saying that since I stated fork() is terrible that I am not advocating for spawning new processes via any of the variants of exec() since they all depend on fork(). I directly stated posix_spawn() was the right technique (despite its deficiencies and a somewhat terrible interface).

My point was that embryonic processes aren't really the right solution since they require exposing a whole bunch to powerful primitives like read/write of remote address spaces in order to spawn processes. That ends up being slow (because each one of those calls is necessarily a syscall and requires manipulating page tables to mess with the other process). It also means to prevent abuse you need to be very carefully control when to revoke those privileges.

The obvious solution is to take all the operations you would have done to the remote process, encode them in some form, and pass them off to a secure agent (in this case the kernel) that can do them in bulk. That solves both perf issues (1 syscall, and no repeated round tripping through multiple address spaces), and the security issue (you no longer need to expose primitives to manipulate the remote process to every process that is allowed to spawn a new one).

[go to top]