Hook action on process creation

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. )