I want to know what program calls a particular executable, including when that executable is used as an interpreter via a shebang line.
This is not quite the same problem as knowing what program accesses a particular file. For example, auditctl -w /usr/bin/myprogram
tells me that the program is being executed by… itself, since the audit event is generated after the successful execve
call.
One option is to replace the executable by a wrapper program, like this…
#!/bin/sh
logger "$0: executed by uid=$(id -u) ruid=$(id -ur) cmd=$(ps -o args= -p $PPID)"
exec "$0.real" "$@"
But this requires moving the actual file, which is disruptive (the file can't be read-only, it clashes with modifications made by a package manager, etc.). And it doesn't work if the program is used as an interpreter for a script, because shebang doesn't nest. (In that case, auditctl -w /usr/bin/interpreter
does give a useful result, but I want a solution that works for both cases.) It also doesn't work for setuid programs if /bin/sh
is bash since bash drops privileges.
How can I monitor executions of a particular executable including uses of the executable as a shebang interpreter, and in particular log useful information about the calling process (not just the PPID but at least the process name or the parent executable path, ideally also the invoking user and arguments)? Preferably without replacing the file with a wrapper. A Linux-specific solution is fine.
Best Answer
This would be hacky, but if it's a dynamically linked executable, you could set up a global preload in
/etc/ld.so.preload
which would only trigger a logging hook if it detected you were in the right executable.Something like:
The obvious disadvantage of this approach is it would slightly delay the execution of each dynamically linked executable on your system, but my measurements indicate the delay is quite small (<1ms where fork+exec costs about 2ms).
As for the dropped permission problem, you could have a small setuid-root binary that will unconditionally read and echo its grandparents proc files (the
status
file, most likely), possibly if and only if its parent is the executable whose parents you want to log. You could then spawn that setuid executable inside your logging hook to obtain the info on the executables parent (grandparent of the setuid helper).