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.
auditctl -a exit,always -F arch=b64 -S execve
will log every exec call and the parameters (so a script will show with the binary as the shell and $0 as the script name), so you could build a history of PIDs and track back callers... but that's gonna impact performance!auditctl -w /path/to/file -p x
is enough if the program is called as an interpreter via a shebang — that gives me the path to the script, which is the relevant information in that case. But that doesn't give useful information if the executable is called explicitly: the PPID is logged but not other information about the parent command.-S execve
rather than-w /path/to/file
) and keep track of PIDs. Messy :-(auditctl
to give the executable a different key than the rest of theexecve
conditions and when you find an instance of the monitored executable you can do anausearch -p
for that PPID for a time period within a minute or so the time on the target execve's invocation. Since the PID is unlikely to get recycled quite that fast it should be pretty simple to track back from that provided you're starting from a reliably constructed and succinct list ofexecve
's you actually care about.