Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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

share|improve this question
    
What do you want to use this for? – michas Feb 13 at 21:37
1  
LD_PRELOADing a custom fork should do the trick for most applications. – PSkocik Feb 13 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? – Gilles Feb 13 at 21:56
    
@michas: investigations, auditing. Will update the question. – Wadih M. Feb 13 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 at 22:02

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).
share|improve this answer
//fakeExec.c
#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. )

share|improve this answer
    
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. – Gilles Feb 13 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 at 23:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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