2 ms·
> Do you think it would be practical to reuse the same socket for everything then and use the incoming PID as a filter rather than creating a new file per invoc
by skissane 4y ago
> Do you think it would be practical to reuse the same socket for everything then and use the incoming PID as a filter rather than creating a new file per invocation?
I was thinking you could have two environment variables:
SHELL_SOCKET=<path to the Unix domain socket the shell is listening on>
SHELL_CLIENT_ID=<some kind of unique ID, like a UUID>
Now, SHELL_SOCKET is the same for every subprocess. But every new process you fork, you set a different value for SHELL_CLIENT_ID. And part of the protocol, is that upon connecting, the client has to send you SHELL_CLIENT_ID, and you check it is a valid one in your memory, and you reject the connection if it isn't. Since you control the protocol, you could also insist the client sends you the PID, and match that too. I wouldn't even bother trying to stop clients lying about their own PID – if someone wants to play those kind of silly games, why stop them? If the socket file ownership/permissions make it accessible by the user only, then either the user themselves is being silly, or else their account is already compromised by an attacker/malware.
So then you don't even need to bother with SO_PEERCRED/SCM_CREDENTIALS/etc if you don't want to.
And, with respect to the "multiple subprocesses" problem–the simplest thing you could do, is decide to only accept one connection per a SHELL_CLIENT_ID, the first one wins, the second gets rejected. There's many more complex solutions (like have some kind of locking so subprocesses could take turns at output but doing it in a way which wouldn't corrupt the output), but that would be the simplest.
You could even encode both into a single environment variable, e.g: SHELL_SOCKET=<client UUID>:<path to shell socket>