14

I want to exec a script when a new root process spawns. (on Linux) How can I simply do that ?

Thanks

1
  • This is an interesting question , but is there a practical application for this? I have been wracking my brain and I'm drawing a blank... Nov 9, 2010 at 4:21

4 Answers 4

10

This sounds like a perfect job for auditd. Once you have auditd running, a default service on modern RedHat based systems, you can craft a rule that will do exactly what you want by executing

auditctl -a task,always -F uid=0

Breaking this command rule down, making excessive use of the man page, we find that:

   -a list,action
          task       Add  a  rule to the per task list. This rule list is used
                     only at the time a task is created -- when fork() or
                     clone() are called by the parent task. When using this
                     list, you should only use fields that are known at task
                     creation time, such as the uid, gid, etc.
          always     Allocate an audit context, always fill it in at syscall 
                     entry time, and always write out a record at syscall exit
                     time.

So always write out a record for this action whenever a fork or clone system call exits.

The final option can be thought of as a filter string, in our use -F uid=0 simply restricts us to cases where the uid of the process owner is 0.

Note that this rule can be executed at run time by making sure that auditd is properly configured, and adding the rule
-a task,always -F uid=0
into the relevant file for your distribution, most likely /etc/audit/audit.rules

Just keep in mind that this will be pretty dang noisy, and whomever is doing your log reviews will need to be prepared for it.

4
  • Actually, now that I wrote this up, I suddenly realize that I answered the question in the title, and not the question in the question. I hope it is still useful.
    – Scott Pack
    Feb 2, 2011 at 16:36
  • 1
    Why are you sometimes using pid=0 and sometimes uid=0
    – Dakusan
    May 30, 2017 at 21:10
  • 1
    @dakusan Mostly because I need an editor. Fixed now.
    – Scott Pack
    May 30, 2017 at 21:16
  • record is stored at /var/log/audit/audit.log.
    – VictorV
    Mar 11, 2022 at 3:07
3

I don't think there's a clean way to do this without recompiling your kernel with CONFIG_PROC_EVENTS and/or CONFIG_KPROBES (although I'd love to know if there is a way of doing it, so I've upvoted your question).

I did have an idea of using iwatch/inotify for directory creation inside /proc but it didn't seem to work, neither did auditctl. It looks like your best choice, although dirty, is to continually parse ps for a change from a script. The following Perl code would do it, although would be prone to miss some and ignores ps (as it would otherwise trigger itself):

perl -e 'my %pids; while(1) { my @pids = `ps -U root -u root`; foreach (@pids) { next if /ps$/; ($pid) = /^\s*(\d+)\D/; if (!$pids{$pid}) { $pids{$pid}++; print "Process $pid created (" . `cat /proc/$pid/cmdline` . ")\n"; } } }
1
  • You're missing a single quote at the end of your code. Can't edit it as SO requires at least 6 characters to change. Also, for all users, use "-ax" instead of "-U root -u root"
    – Dakusan
    Apr 6, 2017 at 18:39
2

You can do this using exec-snoop (based on ebpf), tracepoints, audit, the netlink process connector, and some other mechanisms. I've written a comparison of all the methods here.

1

The best way I can think of would be to build off the snoopy library. snoopy is a very small shared library that gets hooked into /etc/ld.so.preload and wraps around execve() system calls. It's configurable to log all exec()'s, or just those from root. In it's current incarnation, snoopy logs to syslog every time a matching event (a syscall to execve()) happens. It's not a large program though (a couple hundreds lines of code, at most), and could be modified without that much difficulty to execute a script instead of (or in addition to) logging the activity. Snoopy is written in C.

A few things to note:

  • If you run a script every time a root process is spawned, your script will be a root process, which will need to spawn the script again, which will be another root process, etc. Be careful that you don't get into a loop there.
  • On a typical Linux box, there are a lot of processes that get run as root, and spawned regularly. For example, cron may spawn system cronjobs as root every minute or few minutes. If you're just looking for this to happen when a user logs in as root, it will be more work.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .