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.


  • What do you want to use this for?
    – michas
    Feb 13, 2016 at 21:37
  • 1
    LD_PRELOADing a custom fork should do the trick for most applications.
    – PSkocik
    Feb 13, 2016 at 21:40
  • 1
    No. If you did that, creating a process would trigger the script which would trigger the script which would trigger the script… What problem are you actually trying to solve? Feb 13, 2016 at 21:56
  • @michas: investigations, auditing. Will update the question.
    – Wadih M.
    Feb 13, 2016 at 21:59
  • @Gilles: Thanks for your comment, I updated my question. It would be to allow to do an action upon spawning of the processes, for example logging it.
    – Wadih M.
    Feb 13, 2016 at 22:02

2 Answers 2


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).
#include <unistd.h>
#include <stdio.h>
#include <sys/syscall.h>
int execve(const char *path, char *const argv[], char *const envp[]) {
  printf("Execing \"%s\"\n", path);
    return syscall(SYS_execve, path, argv, envp);

In the terminal:

$ gcc -fPIC -shared fakeExec.c -o fakeExec.so
$ export LD_PRELOAD=$PWD/fakeExec.so 

And now you should get every new execed file logged to stdout.

A fork wrapper would apparently require a little bit more work to get done right.

( The trivial fork wrapper (like the above but for fork rather than execve) sort of works, but leads to some setgpid errors in the processes spawned with it.

Apparently the libc fork function a little bit of additional stuff, which I don't quite understand. )

  • The problem with this approach is that in practice, it probably won't work, because LD_PRELOAD doesn't affect internal calls made inside the C library. So this affects programs that call execve directly, but not programs that call execvp, system, etc. Feb 13, 2016 at 22:56
  • @Gilles Musl appears to route all the exec functions through execve (that's why I chose that one). Glibc probably does too, because I've tried this and it does seem to work. This is very tentatic and hacky, though. No doubt about it.
    – PSkocik
    Feb 13, 2016 at 23:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.