Hook action on process creation

inotifyprocess

Is it possible to hook a script execution on each process creation?

Essentially the equivalent of inotifywait to monitor disk activity but applied to the process table.

It would be to allow to do an action upon spawning of the processes, for example logging it, cgset it, other. I can see the challenge that it would recursively apply on the new processes. But instead of polling the process table as fast as possible to catch changes which would be vulnerable to race conditions, is there a better way.

Thanks

Best Answer

First, process creation is rarely a useful event to log and it's irrelevant for security (except for resource limiting). I think you mean to hook the execution of programs, which is done by execve, not fork.

Second, the use cases you cite are usually best served by using existing mechanism made for that purpose, rather than rolling your own.

  • For logging, BSD process accounting provides a small amount of information, and is available on most Unix variants; on Linux, install the GNU accounting utilities (install the package from your distribution). For more sophisticated logging on Linux, you can use the audit subsystem (the auditctl man page has examples; as I explained above the system call you'll want to log is execve).
  • If you want to apply security restrictions to certain programs, use a security framework such as SELinux or AppArmor.
  • If you want to run a specific program in a container, or with certain settings, move the executable and put a wrapper script in its place that sets the settings you want and calls the original executable.

If you want to modify the way one specific program calls other programs, without affecting how other programs behave, there are two cases: either the program is potentially hostile or not.

  • If the program is potentially hostile, run it in a dedicated virtual machine.
  • If the program is cooperative, the most obvious angle of attack is to run it with a different PATH. If the program uses absolute paths that aren't easy to configure, on a non-antique Linux system, you can run it in a separate mount namespace (see also kernel: Namespaces support). If you really need fine control, you can load a library that overrides some library calls by invoking the program with LD_PRELOAD=my_override_library.so theprogram. See Redirect a file descriptor before execution for an example. Note that in addition to execve, you'll need to override all the C library functions that call execve internally, because LD_PRELOAD doesn't affect internal C library calls. You can get more precise control by running the program under ptrace; this allows you to override a system call even if it's made by a C library function, but it's harder to set up (I don't know of any easy way to do it).
Related Question