Andrey Semashev wrote:
Well, $HOME/bin is before /usr/bin on my system.
This means that if an attacker gains access to $HOME he can override /usr/bin/anything, unless you watch $HOME/bin like a hawk.
I think, a process could also modify the system-wide PATH variable, at least on some Windows versions. IIRC, some installers (Visual Studio? Intel compiler? I can't remember) did that at some point. I don't know if that's the case now.
You need root for that.
That is somewhat better. It does exclude PATH from the lookup, that's for sure. But consider that the application could use a custom build of Boost and be installed in /opt. What if the application also wants to use a custom addr2line from its /opt/my_app/bin?
It wouldn't be hard for Stacktrace to provide a function to set the actual path to addr2line, if we agree that spawning a helper process is acceptable in principle.
The full path does not solve the problem of setting up environment for the process though. E.g. I don't have a way to drop privileges of root before executing addr2line.
Dropping privileges could perhaps work for addr2line which takes a filename rather than a PID but it wouldn't work for utilities that are PID-based such as atos. If the program is root, the utility would also need root in order to inspect its address space and locate the module based on the address. I think.
Security issues aside, there is also a matter of controlling the child process. What if it hangs? Or crashes? How does it affect the master application? What if the master crashes (i.e. how can you ensure you don't leave a zombie process)? What will you do if you exhaust the limit of running processes in the system (i.e. if the app itself is not able to spawn its processes because of a bunch of running addr2line)?
Very similar questions can be posed towards the current Windows implementation. There isn't that much of a difference between using a helper process and doing the same work in-process. In fact, if your process has just crashed, it's better to do the work from another process, because its memory would be intact. (COM by the way isolates the client from whether the server is in-process or not, so the debug engine can well spawn a process under the hood, and we wouldn't be any wiser. Nor should we be.)
Then, there are performance implications of running a process for each function call.
That's what I tried to address with my API suggestions.